📎 Unreleased docs. This is the next version (from main), features here may change or not be in a release yet.See the latest release →

Scanners

sarif-import

On this page
  • Control: the control each import names in components[].imports
  • Tool: none. Draugr reads a file; the tool that wrote it ran somewhere else.
  • Target: file (a SARIF 2.1.0 log)
  • Effects: none
  • Status: ✅ implemented

Import another scanner's SARIF walks through a pipeline that writes the file, binds it to its commit, and scans.

What it does

Reads a SARIF file a component imports and adds its findings to the control the descriptor names, as though one of that control's scanners had produced them. Each finding then takes the component's exposure and criticality into its priority, counts toward the gate, and appears in the fix list and every report beside the findings Draugr's own scanners made.

The file is read as SARIF 2.1.0:

  • Severity comes from each result's numeric security-severity property, the convention GitHub code scanning reads, inherited from its rule where the result has none. A result without one, in a file Bandit wrote, is rated from its issue_severity and issue_confidence (see Bandit). Any other result falls back to its level, mapped as every other SARIF level is: error to high, warning to medium, note to low.
  • Package and fix come through only where the file carries them in the properties Draugr reads. Without them a finding becomes a "Fix " action rather than an upgrade.
  • The tool is the file's own tool.driver, so a finding says which product found it.

What the report says about the file

Draugr did not run the tool, so the report states what it knows about the file instead, under Measured against and in results.sarif:

FieldValue
toolthe tool's name and version, as the file states them
filethe path the descriptor gave
writtenwhen the file says its run ended (invocations[].endTimeUtc), or else the file's modification time
severitywhere severities came from: security-severity, issue_severity and issue_confidence, SARIF level, or a count of each
committhe commit the file was checked against, or not stated
componentthe component that imports it
sha256the file's content, so a run can be checked against the file it read

Bandit

A result in a run whose tool.driver.name is Bandit is rated from the two result properties Bandit writes, issue_severity and issue_confidence, each LOW, MEDIUM or HIGH, by the table below.

issue_severityseveritywith issue_confidence LOW
HIGHhighmedium
MEDIUMmediumlow
LOWlowlow

Bandit already writes the level from issue_severity, so the rating differs from the level only for a result Bandit rates LOW confidence, which is one level lower. Bandit has no rung above HIGH, so nothing it reports is critical. A result with an issue_severity outside the three, such as UNDEFINED, keeps its level, and a result carrying a security-severity keeps that.

The report prints the rating on the finding's evidence line in Bandit's own terms, issue_severity medium, with issue_confidence low added where Bandit rated the confidence LOW. results.sarif keeps Bandit's level and adds the result property draugr/rating, which holds the severity, that line, and both properties with Bandit's value. A file another tool wrote is not rated this way, whatever its properties are called.

Commit

A file left from an old run reads exactly like a current scan. Where the file names the commit it scanned, in runs[].versionControlProvenance, Draugr holds it to the commit this run reads:

  • The same commit: the file is read, and commit names it.
  • A different commit: the run stops with an error naming both. Run the tool again on this commit, or remove the import.
  • No commit named: the file is read and listed under Caveats as unbound-imports, because nothing ties its findings to this code. config.gate.failOnCaveats: [unbound-imports] makes that fail the run.

A component with one repository is held to it whatever address the file gives, because a tool records the remote it saw and the descriptor may name the same repository by a local path. Entries that list one repository at one revision, a subtree each, count as one. With several distinct repositories, the address has to name one of them.

Errors

A file that is missing, unreadable, empty, not SARIF, a SARIF version other than 2.1.0, or a log with no runs stops the run as a scanner that could not run does, and --allow-scan-errors accepts it. A valid file with no results is a clean result.

License & terms

No third-party tool is executed or bundled, so the scanner carries only Draugr's own license. The file is the reader's; its tool's terms governed whoever produced it, before Draugr read it.

Data

Nothing. The scan reads the file the descriptor names, on the machine running Draugr, and resolves the component's repository revision with git, locally for a path and with git ls-remote for a remote.