To reduce SAST false positives, scan only the code a pull request changes, switch off rule groups that never apply to your stack, suppress confirmed non-issues with a written reason, and check whether flagged code is reachable by untrusted input. Do these in that order and measure the share of findings your team fixes.
Key takeaways
- Noise is normal. OWASP lists high false positives as a core SAST weakness, and eslint-plugin-security says its findings need human triage.
- Reduce repeats first: diff-aware scans stop old findings returning on every pull request.
- Tune rules by suite or ruleset, not by ignoring the whole report.
- Always record why a finding was dismissed.
Why does SAST produce false positives?
SAST reasons about code without running it, so it guesses at values and paths. OWASP notes that it is hard to prove a reported issue is a real vulnerability and that tools struggle with code that cannot be built without libraries or build instructions. Pattern tools flag risky calls whether or not untrusted data reaches them.
Step 1: How do I stop the same findings appearing again?
Run diff-aware scans on pull requests. Semgrep's docs define a diff-aware scan as one that shows only findings caused by changes in files since a Git baseline, set with SEMGREP_BASELINE_REF. One caveat from the docs: diff-aware scans consider only changes within modified files and do not support cross-file analysis. Bandit offers a baseline file for the same purpose: generate a JSON report, then pass it with the -b flag so known issues are skipped.
Step 2: Which rules should I turn off?
Start from a narrower suite and widen it later. CodeQL's default suite runs a default set, while security-extended adds lower severity and lower precision queries, and security-and-quality adds maintainability queries. If you are drowning, stay on the default. In Bandit, filter to high severity with the -lll flag. Add the noisier groups back one at a time.
Step 3: How do I suppress a finding the right way?
Suppress per finding with a reason, never by deleting the rule everywhere. gosec supports a nosec comment with a justification, and opt-in flags reject bare or unexplained suppressions. Semgrep supports a nosemgrep comment, optionally with a rule ID, and platform triage lets you pick an ignore reason. The docs do not describe a way to attach a reason inside the nosemgrep comment itself, so put the reason in the pull request or ticket.
Step 4: How do I use reachability?
Ask whether untrusted input can reach the flagged code. A finding in code no entry point calls is lower priority than one on a request handler. Safeguard publishes an interactive demo of reachability analysis, which filters findings by whether code is actually reachable.
Click through it at your own pace, or open it full screen.
Step 5: Should I write custom rules?
Write a custom rule when the same false positive repeats because of an internal wrapper or sanitizer. Semgrep rules are files you keep in your repository. Keep your own rules separate, because Semgrep's FAQ says rules you write are unrestricted only if they are not derived from Semgrep's community or Pro rules.
Step 6: What metric should I track?
Track the share of findings your team fixes within a sprint. A rising fix rate means trust is rising. Raw finding counts only show how much the tool shouts.
Step 7: When do I add a second signal?
Add runtime evidence for findings that stay disputed. A DAST test or an IAST sensor can confirm a flaw is reachable in a running app. See SAST vs DAST vs IAST.
Frequently asked questions
What is an acceptable SAST false positive rate?
There is no sourced universal number. Measure your own fix rate on a real repository and aim for it to rise over time.
Are false positives a sign the tool is bad?
Not necessarily. OWASP lists them as a general SAST weakness. The question is how tunable the tool is.
Should I ignore low severity findings?
You can hide them from pull requests while keeping them in a scheduled scan report.
Can AI triage remove false positives?
Some products offer it, and GitLab lists false positive detection as a paid Duo feature. Treat it as a filter and spot check its decisions.
Sources
- OWASP Source Code Analysis Tools: https://community.owasp.org/Source_Code_Analysis_Tools
- Semgrep customize CI jobs: https://docs.semgrep.dev/deployment/customize-ci-jobs
- Semgrep ignoring files, folders and code: https://docs.semgrep.dev/ignoring-files-folders-code
- Semgrep FAQ: https://docs.semgrep.dev/faq/overview
- Bandit getting started: https://bandit.readthedocs.io/en/latest/start.html
- gosec: https://github.com/securego/gosec
- eslint-plugin-security: https://github.com/nodesecurity/eslint-plugin-security
- GitHub, customizing advanced setup for code scanning: https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning
- GitLab SAST docs: https://docs.gitlab.com/user/application_security/sast/
Last reviewed: 19 October 2026.