Safeguard
Developer Tools•

How do you prove a SAST finding is real with a failing test?

Write a unit test that feeds the dangerous input to the flagged code. If it fails, the finding is real and the test guards the fix. Steps and an example.

Safeguard Security Team
4 min read

Write a unit test that sends the dangerous input from the scanner's data flow into the flagged function and asserts safe behaviour. If the test fails, the finding is real and you now have a regression test. If it passes for every hostile input you can think of, you have evidence for a false positive.

Why a test beats an argument

Debates about whether a finding is exploitable can run for days. A test settles it in minutes and stays in the repository. It also turns the fix into a normal code change that reviewers understand.

OWASP notes that with source code analysis tools it can be hard to confirm that a reported issue is an actual vulnerability. A test is the cheapest confirmation available to a developer who owns the code.

Steps

  1. Read the data flow. Most SAST reports show a source, where untrusted data enters, and a sink, where it does harm. If the terms are new, read what a source and a sink are in SAST.
  2. Find the entry point. Pick the function nearest the sink that you can call from a test, or the handler that receives the request.
  3. Choose hostile inputs. For injection, a quote and a comment marker. For path traversal, a parent directory sequence. For cross site scripting, markup characters. Keep the inputs harmless to your test environment.
  4. Assert the safe outcome. The query is parameterised, the path stays inside the base directory, or the output is encoded. Test the property, not the exact string.
  5. Run it. A failure confirms the finding. Record the test name in the finding.
  6. Fix and re-run. The same test should now pass, and the next scan should drop the finding.

What the result means

Test resultMeaningNext step
Fails with hostile inputTrue positiveFix, keep the test
Passes, and you can name the controlLikely false positiveSuppress with the control and the test as evidence
Passes, but only because the setup is unrealisticUnknownMove the test closer to the real entry point
Cannot be tested in isolationUnknownTry an integration test or a DAST replay

Cautions

A passing test shows only that those inputs were safe. Try several variants before you call something false. Do not weaken the test to make the build green. And avoid pointing hostile inputs at shared databases or live services. Use a local or throwaway instance.

Use the test in the suppression

If you decide the finding is false, the suppression comment can name the test, as described in writing a suppression comment that survives review. A later reader can run it instead of trusting your word.

Try it yourself

Open the demo and trace one finding from the flagged line back to where its input originates.

Click through it at your own pace, or open it full screen.

One factual note on Safeguard

Safeguard offers autonomous remediation with fix pull requests, off by default with every category on Manual. If you want a quick look at your own code, the free scan at gold.safeguard.sh/scan is a no-account place to start.

Quick check

Does a passing test prove a finding is false?

No, it only shows those inputs were handled. Try several hostile variants and name the control that protects the code.

What if I cannot call the flagged code from a test?

Test at the nearest callable entry point, or replay the request against a local instance.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.