All integrations

CodeQL Integration with DefectDojo

CodeQL Integration with DefectDojo

CodeQL is GitHub's semantic code analysis engine, which GitHub gained through its 2019 acquisition of Semmle. It builds a relational database from a codebase and runs queries against it, so a result can carry the full data flow from an untrusted source to a dangerous sink rather than just the offending line. GitHub publishes standard query packs for languages including C and C++, C#, Go, Java and Kotlin, JavaScript and TypeScript, Python, Ruby, and Swift. CodeQL runs through the CodeQL CLI or GitHub code scanning, and its native output format is SARIF.

CodeQL Integration with DefectDojo

We run CodeQL because its path queries explain how tainted data reaches the problem, which saves a lot of time during triage. GitHub's code scanning view is fine for one repository. We have many repositories plus findings from other tools, so CodeQL results go into DefectDojo, where each alert becomes a Finding on the right Asset, titled by the query that raised it, deduplicated by CodeQL's own fingerprint, and held to the same SLAs as everything else.

Why CodeQL Matters

Many serious application flaws are data flow problems: input that crosses several functions before it reaches a query, a template, or a file operation.

  • Path queries trace a value from source to sink, step by step, which shows the developer exactly where to add validation.
  • Security queries carry a security-severity score out of 10, the same value GitHub uses to rank code scanning alerts.
  • Queries are tagged with CWE identifiers, so results line up with other SAST tools and secure coding standards.
  • Each query declares a precision, which helps decide what to triage first.

Advantages of This Integration

What a dedicated CodeQL parser in DefectDojo gives us:

  • Titles that name the query. Findings are titled with the query ID and its short description, such as py/sql-injection: SQL query built from user-controlled sources, so they can be filtered, assigned, and suppressed by query.
  • Stable deduplication. DefectDojo matches on CodeQL's SARIF fingerprint first and falls back to a hash of query ID, file path, and line when a report has none.
  • Severity from CodeQL itself. The security-severity score maps to Critical through Low, and non-security queries fall back to the SARIF level.
  • Data flow on the Finding. For path queries, each step of the flow is written into the description.
  • Lifecycle across commits. Reimporting each scan into the same Test mitigates alerts that were fixed and reactivates regressions.

How This Integration Works

DefectDojo imports CodeQL output with the CodeQL Scan scan type. CodeQL SARIF can still be imported with the generic SARIF scan type, but the CodeQL scan type is preferred because of its query-based titles and severity handling.

1. Generate SARIF. With the CodeQL CLI:

codeql database create db --language=python --source-root=.
codeql database analyze db --format=sarifv2.1.0 --sarif-add-snippets --output=results.sarif

Including snippets puts the flagged code in each Finding's description. The CodeQL GitHub Action can do the same with its add-snippet option set to true.

2. Import it. In the UI, open the Engagement, choose Import Scan Results, select CodeQL Scan, and upload the SARIF file. In a pipeline, use the API in Community Edition or DefectDojo Pro:

curl "https://YOUR_INSTANCE/api/v2/import-scan/" \
  -H "Authorization: Token $DD_API_TOKEN" \
  -F "scan_type=CodeQL Scan" \
  -F "file=@results.sarif" \
  -F "product_name=billing-api" \
  -F "engagement_name=CI" \
  -F "auto_create_context=true"

DefectDojo Pro users can use Universal Importer instead:

universal-importer import \
  --defectdojo-url "https://YOUR_INSTANCE.cloud.defectdojo.com/" \
  --scan-type "CodeQL Scan" \
  --report-path "./results.sarif" \
  --product-name "billing-api" \
  --engagement-name "CI" \
  --auto-create-context

3. Reimport per branch. Send each new scan of the same branch to /api/v2/reimport-scan/ for the same Test so alert history stays in one place.

Data Granularity: What Gets Imported

DefectDojo Field Source in CodeQL SARIF Notes
Title ruleId and rule shortDescription Falls back to the generic SARIF title if either is missing
Severity Rule security-severity, else result or rule level 9.0+ Critical, 7.0 to 8.9 High, 4.0 to 6.9 Medium, above 0 Low, 0 Info; error High, warning Medium, note Info
CVSS v3 Score security-severity The raw numeric score
Description Result message, snippet, rule name and descriptions, code flows Adds query precision, problem kind, and security severity
CWE Rule tags external/cwe/cwe-NNN Every CWE is kept; the last one is the primary CWE
Vuln ID from Tool ruleId The query ID
File Path / Line Physical location URI and startLine One Finding per location in a result
Unique ID fingerprints or partialFingerprints Used first for deduplication
References Rule helpUri Or the help text when it is a URL
Mitigation Result fixes Only when the SARIF includes fix descriptions
Tags Rule and result tags external/cwe/ prefix stripped, for example security, cwe-089
Status suppressions Suppressed results import as inactive false positives
Date Last invocation endTimeUtc When the run records it
Finding type Static All CodeQL Findings
Deduplication Unique ID, then hash code Hash fields: query ID, file path, line

Results whose SARIF kind is anything other than fail are skipped.

Use Cases

Across an organization's repositories: Every repository runs CodeQL in CI and reimports into a Test per repository and branch. Security leads see open alerts by query across all Assets, and can spot the query that keeps firing in many codebases.

For release gates: A pipeline step queries DefectDojo for new Critical or High CodeQL Findings on the release branch. Findings that were triaged as false positives or risk-accepted earlier don't block the release.

Comparing SAST tools: Teams running CodeQL alongside another static analyzer import both into the same Asset and compare by CWE and file path, which shows where the tools agree and what each one misses.

Developer remediation: With the data flow and snippet in the description, a developer assigned a Finding (or a Jira issue pushed from it) sees the source, the path, and the sink without opening the CodeQL database.

Operational Tips

  • Always pass --sarif-add-snippets. Without it, Findings lack the flagged code and are slower to triage.
  • Non-security queries have no security-severity score, so a code quality query at error level imports as High. Use minimum_severity or the query suite you run to keep quality results out of security SLAs.
  • Suppressions recorded in the SARIF arrive as false positives. If your team suppresses alerts in code, review those occasionally instead of assuming they are all correct.
  • Use one Test per repository and branch. Mixing branches in one Test makes reimport close alerts that only exist on the other branch.
  • A result with several locations becomes several Findings, one per location. That is expected, but it can make counts higher than the alert count in GitHub.
  • Filter on Vuln ID from Tool (the query ID) when you want to risk-accept or bulk-update every Finding from one query.