Skip to content
Visibility internal Owner _ Approver _ Created _ Updated _

Triage reference

Contents

  • Per-tool noise patterns
  • OWASP Top 10:2025 mapping
  • Severity calibration

Per-tool noise patterns

Semgrep

  • p/security-audit is deliberately high-recall. Expect a lot of low-value hits.
  • Taint rules stop at function boundaries in dynamic languages. A “user input reaches SQL” hit may pass through a sanitiser Semgrep couldn’t follow — and the reverse: a missed flow doesn’t mean the path is clean.
  • Test files, fixtures and migration scripts produce constant false positives. Check the path before caring.
  • ORM query builders often trip raw-SQL rules. Parameterised is parameterised.

Trivy

  • --scanners vuln reports every CVE in the dependency tree, including ones in code paths you never call. Prioritise by whether the vulnerable function is reachable, not by CVSS alone.
  • Base-image CVEs with no fix available (--ignore-unfixed filters these) will otherwise dominate the count and drown out application findings.
  • Transitive dev dependencies matter far less than direct runtime ones.

Gitleaks

  • Scans full git history, so it finds secrets that were committed and later removed. Those are still real — the credential is in the history and must be rotated, not just deleted. Removing the commit does not un-leak it.
  • High-entropy strings that aren’t secrets: test fixtures, example keys in docs, UUIDs, base64 test data.
  • If a real secret is found, rotation comes first, before any other finding.

Checkov

  • Flags cloud defaults that may be intentional. Public read on a bucket serving static assets is fine; on one holding user uploads it is not. Checkov can’t tell the difference.

ZAP

  • The baseline scan reports many missing-header findings. Real, but usually low severity and fixable in one place.
  • Alerts on error pages and redirects are frequently artefacts of unauthenticated crawling rather than genuine issues.
  • Without an authenticated session, ZAP only sees the logged-out surface — which is a small fraction of the app. Note this as a coverage gap.

Nuclei

  • Very low false positive rate by design — templates check for specific responses. Treat a Nuclei hit as probably real.
  • But it only finds what a template exists for. Silence means nothing about custom application logic.

OWASP Top 10:2025 mapping

Use these categories in the report so findings group sensibly.

CategoryTypically found by
A01 Broken Access Control (now includes SSRF)manual review; scanners rarely
A02 Security MisconfigurationCheckov, ZAP, Trivy misconfig
A03 Software Supply Chain FailuresTrivy, SBOM review
A04 Cryptographic FailuresSemgrep, manual review
A05 InjectionSemgrep, ZAP, Nuclei
A06 Insecure Designmanual review only
A07 Authentication Failuresmanual review; some Semgrep
A08 Software/Data Integrity FailuresTrivy, CI config review
A09 Logging & Alerting Failuresmanual review only
A10 Mishandling of Exceptional Conditionsmanual review; error-path reading

Note the pattern: half these categories have no automated coverage at all. A report built purely from scanner output has a hole in exactly the places that rank highest.


Severity calibration

Rate by exploitability in this application, not the scanner default.

Critical — unauthenticated remote access to data or code execution. Live credentials in a repo that a third party can read.

High — authenticated but cross-tenant. Privilege escalation. Injection reachable from a user-controllable field.

Medium — requires an unlikely precondition, or exposes non-sensitive internals. Missing defence-in-depth on a path already protected elsewhere.

Low — hardening. Missing headers, verbose errors, outdated dependency with no reachable vulnerable path.

Dismissed — not reachable, not applicable, or the flagged pattern is already mitigated. Always record why; the next run will flag it again.

When downgrading a scanner’s own rating, say so explicitly in the report and give the reason. Silent downgrades are how real findings get lost.