Skip to content

/cso import-sarif: results with a uriBaseId are dropped as partial — semgrep and trivy SARIF never reach the audit #3011

Closed

Description

@Eniot666

Summary

gstack-cso import-sarif drops every SARIF result whose artifactLocation
carries a uriBaseId, unless the run declares that base in
originalUriBaseIds and the base is exactly file://<sourceRoot>/. The
import CLI always normalizes against the fixed root /source
(lib/cso/cli.ts:348, importSarif(..., {sourceRoot: '/source'})), so a base
that points at the real checkout can never match.

semgrep and trivy both emit uriBaseId by default, so all of their results
are dropped: coverage scanner:sarif becomes partial with the gap
A SARIF result could not be safely normalized., and the result yields 0
candidates
. A real finding from either scanner is dropped exactly like a
false positive, and never reaches the audit.

Version: gstack 1.91.9.0 (96764e80), semgrep 1.177.0, trivy 0.74.0, Linux,
no Docker (scanners run natively, SARIF imported with import-sarif).

Where it happens

lib/cso/scanners.ts, in the result loop (lines ~360-378 in 1.91.9.0):

if (artifact.uriBaseId !== undefined) {
  const baseId = str(artifact.uriBaseId);
  const bases = obj(run.originalUriBaseIds);        // throws 'Expected object' if absent
  const base = str(obj(bases[baseId]).uri);
  if (base !== `file://${root}/` && base !== `file://${root}`) throw new Error('Unsafe location');
}
...
} catch (error) { gap(... ? 'UNSAFE_LOCATION' : 'INVALID_OUTPUT', 'A SARIF result could not be safely normalized.'); }
  • semgrep: results carry "uriBaseId": "%SRCROOT%" and the run has no
    originalUriBaseIds. obj(undefined) throws Expected object →
    INVALID_OUTPUT.
  • trivy: results carry "uriBaseId": "ROOTPATH", and the run declares
    originalUriBaseIds.ROOTPATH.uri = "file:///path/to/checkout/", which is not
    file:///source/ → Unsafe location → UNSAFE_LOCATION.

The uri itself is relative and inside the repo in both cases
(lib/x.test.mjs, Dockerfile).

Reproduction

semgrep --config=p/secrets --metrics=off --sarif -o semgrep.sarif .   # any repo with one finding
trivy fs --scanners misconfig --format sarif -o trivy.sarif .         # a Dockerfile without HEALTHCHECK
gstack-cso-launcher start --repo . --budget 120
gstack-cso-launcher import-sarif <run> semgrep.sarif
gstack-cso-launcher import-sarif <run> trivy.sarif
gstack-cso-launcher inspect <run>   # scanner:sarif partial ×2, 0 candidates

Calling importSarif directly on the same files:

Input Status Candidates Gap
semgrep.sarif as emitted partial 0 INVALID_OUTPUT
trivy.sarif as emitted partial 0 UNSAFE_LOCATION
same files, uriBaseId removed (relative uri kept) complete 2 / 1 none

Expected

A relative uri that stays inside the source root should normalize whether or
not a uriBaseId is present. Suggestions, in order of preference:

  1. When the uri is relative and safe, ignore uriBaseId if its base is
    undeclared, and resolve the uri against the source root, as other SARIF
    consumers do for %SRCROOT%.
  2. Accept a declared base that equals the real checkout path the run was
    started on, not only the fixed /source.
  3. At minimum, report a distinct gap (e.g. UNRESOLVED_URI_BASE) so users can
    tell "unsafe path" from "base not understood".

Workaround

Strip uriBaseId from results whose uri is relative before importing
(and keep refusing absolute or .. paths). With that, both files import as
complete.

Activity

  1. capy-ai commented on Oct 2, 2026

    @capy-ai
    Contributor

    Fixed in v1.91.13.0 (#3013, merged as f30b7b7): import-sarif resolves semgrep's %SRCROOT% and trivy's ROOTPATH through explicit mappings captured from real scanner output; rejected results are counted with rule, base and path. Run /gstack-upgrade, then start a new Claude Code session. Thanks for the report. Reopen if you still see it after upgrading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions