Contextual understanding instead of pure pattern matching
Classic SAST tools like Semgrep or SonarQube scan code for known patterns and flag matches regardless of surrounding context. Claude reads the same code with an understanding of data flow, business logic, and call context. This article shows how the two approaches complement each other and what a systematic, Claude-assisted security review of a pull request looks like in practice.
Table of Contents
- 1. How classic SAST tools fundamentally work
- 2. What contextual understanding means in practice
- 3. Why the two approaches complement rather than compete with each other
- 4. Prompt strategy for a systematic pull request review
- 5. A review run walked through
- 6. Handling false positives and prioritizing findings
- 7. Integrating into the CI pipeline alongside existing SAST jobs
- 8. Limits: no substitute for pentests and deterministic checks
- 9. Establishing the practice in a team: checklist and conclusion
- 10. Summary
- 11. FAQ
1. How classic SAST tools fundamentally work
Static analysis tools such as Semgrep, SonarQube, or Checkmarx work on a rule basis. They parse source code into an abstract syntax tree or a comparable intermediate representation and match it against a library of known vulnerability patterns: insecure deserialization, missing escaping before an SQL query, hardcoded credentials, or the use of outdated cryptographic functions. If a pattern matches, a warning is generated regardless of whether the affected code path ever comes into contact with untrusted input at all.
This rule-based approach has two central strengths: it is deterministic, meaning the same code produces the same findings on every run, and it is fast enough to run on every commit inside a CI pipeline. The downside is that the rules operate locally at the code level and rarely trace the full data flow through an application. A rule that reacts to a specific function knows neither the origin of the data being passed in nor whether an upstream validation step already rules out the critical case.
2. What contextual understanding means in practice
Claude does not analyze code as an isolated string but within the context of the entire repository, made available to the model through Claude Code or an appropriately prepared context window. When a parameter from an HTTP request is passed into a function, the model can follow the call path across multiple files and determine whether an effective validation or sanitization actually occurs between input and critical use. It is precisely this ability to mentally connect multiple files and call levels that sets the approach apart from pure pattern matching.
The advantage shows up most clearly with vulnerabilities that only emerge from the interaction of several individually unremarkable pieces of code, for example an authorization check that exists but sits in the wrong place in the flow and is therefore rendered ineffective. A rule-based scanner detects that a check exists and reports no finding. Claude can recognize that the order of operations effectively bypasses the check because the sensitive action is already executed before the check runs.
3. Why the two approaches complement rather than compete with each other
Semgrep and SonarQube remain indispensable for a baseline set of checks: they are fast, reproducible, and reliably cover known, clearly definable patterns, such as the use of eval() with user input or the absence of prepared statements in a database query. It is not worth manually or via prompt re-searching for this class of errors at every review when a deterministic rule set finds them reliably within seconds.
Claude delivers the greatest value precisely where classic scanners hit structural limits: business logic errors, flawed authorization chains spanning multiple services, or vulnerabilities that only emerge from the interplay of several changes within one pull request. In practice, an order that works well has Semgrep run as a fast, automated first filter, with Claude then specifically checking the cases a rule-based tool cannot capture in principle.
4. Prompt strategy for a systematic pull request review
An effective prompt for a security review should not ask generically about vulnerabilities but should establish a concrete threat perspective and let the diff be connected to the surrounding code. It makes sense to explicitly instruct Claude to trace, for every changed function, the data flow from input to security-relevant use, rather than looking at the diff in isolation. The following example shows a prompt structure that has proven useful as a starting point in practice.
# Claude Code: systematic security review of a pull request
claude "Run a security review of the current diff (git diff main).
For every changed function, proceed as follows:
1. Identify all input sources (HTTP parameters, database, external APIs).
2. Trace the data flow to the security-relevant use (query, filesystem,
shell, template rendering).
3. Check whether effective validation or sanitization exists between
input and use.
4. Assess authorization: does the change touch data or actions that
require a permission check?
5. Rate each finding by OWASP category and exploitability
(critical/high/medium/low).
Output the result as a table with file, line, category, rating, and a
concrete fix suggestion."
5. A review run walked through
In practice, such a review usually runs in two stages. In the first step, Semgrep, integrated as a CI job, delivers a list of deterministic findings sorted by rule severity. In the second step, this list serves as a starting point for Claude: instead of starting from zero, the model can be instructed to evaluate every Semgrep finding in the context of the surrounding business logic and to additionally look for patterns that Semgrep never checks in the first place due to missing rules.
A concrete example from practice: a pull request adds a new endpoint for exporting user data. Semgrep reports no finding because the query is correctly parameterized. When analyzing the call path, Claude recognizes that the authorization check only requires the existence of a session, not whether the requesting person is actually allowed to access the exported records. This exact class of error, syntactically correct code with flawed business logic, is the real value of the approach.
6. Handling false positives and prioritizing findings
A common misconception is that a Claude-assisted review automatically produces fewer false positives than a rule-based scanner. In practice the problem shifts rather than disappears: instead of structural false positives caused by overly generic rules, occasional misjudgments occur where the model misreads a context, for example missing a validation that lives in a central middleware layer rather than directly at the endpoint.
Every finding should therefore come with a traceable justification and a concrete code path a human can verify within a few minutes, instead of accepting generic warnings without evidence. A proven practice is to explicitly ask Claude for a confidence rating per finding and to flag low-confidence findings separately, so the reviewing team controls prioritization itself instead of treating every reported line the same way.
7. Integrating into the CI pipeline alongside existing SAST jobs
For a robust pipeline integration, it makes sense to run the Claude review as its own step downstream of the Semgrep job, feeding its output in as additional context. This way the fast, deterministic SAST run remains the mandatory gate, while the contextual review appears as a supplementary comment on the pull request without blocking the merge on every uncertain judgment.
A clear separation of responsibilities matters here: a high-severity Semgrep finding should continue to block the merge, since the rule is deterministic and well understood. A Claude finding should initially appear as a commented recommendation confirmed by a person before it becomes a blocker. This staging prevents occasional model misjudgments from stalling the entire development flow.
security-review:
stage: test
needs: ["semgrep-scan"]
script:
- semgrep_output=$(cat semgrep-results.json)
- |
claude -p "Assess the following diff (git diff origin/main) in the
context of these Semgrep findings: ${semgrep_output}. Add findings
that Semgrep cannot detect due to missing context awareness,
especially authorization gaps and flawed business logic." \
--output-format json > claude-review.json
artifacts:
paths:
- claude-review.json
8. Limits: no substitute for pentests and deterministic checks
As valuable as contextual understanding is, a Claude-assisted review replaces neither a penetration test nor a deterministic SAST rule set. A language model's results are not identical on every run, and with very large diffs or repositories that exceed the available context window, relevant code can simply sit outside the reviewed files and go undiscovered as a result.
The approach also hits limits with deeply nested call chains spanning many microservices whose code does not fully live in the same repository, because the model can only analyze what is actually available to it as context. For regulated environments with compliance requirements for complete, auditable review trails, a combination of deterministic SAST, a dedicated pentest, and a Claude-assisted review therefore remains the most robust strategy.
9. Establishing the practice in a team: checklist and conclusion
For rolling this out in a team, a gradual approach has proven effective: leave the existing SAST run unchanged, introduce the Claude review in parallel as a purely commenting step with no blocking effect, jointly evaluate finding quality over several weeks, and only then decide which finding categories should eventually become blockers as well.
A short checklist helps with getting started: phrase the prompt to look at data flow rather than isolated lines, require a confidence rating per finding, feed Semgrep results in as context, and always keep responsibility for the final approval with a person. This produces a review process that combines the speed of classic SAST tools with a language model's contextual understanding, without losing either strength.
| Criterion | Classic SAST (Semgrep, SonarQube) | Claude-assisted review | Recommendation |
|---|---|---|---|
| Speed | Seconds to minutes, on every commit | Minutes, usually on pull requests | SAST on every commit, Claude on pull requests |
| Determinism | Fully deterministic | Results can vary slightly | SAST as a hard gate, Claude as a comment |
| Contextual understanding | Local, per code line or function | Repository-wide, across call chains | Use Claude for authorization and logic errors |
| Known patterns like SQL injection | Very reliable | Reliable, but slower | Keep SAST as the primary source |
| Business logic errors | Usually not detected | Can be detected | Use Claude specifically for logic checks |
| Audit reproducibility | High, same run same findings | Medium, result can vary | Use SAST logs for compliance evidence |
Mironsoft
AI-assisted development, agent workflows, and team processes
Using Claude or other AI tools on the team, but without a clear workflow?
We set up AI-assisted development workflows for teams, from CLAUDE.md conventions to subagent strategies to code review processes that combine human oversight with AI speed.
Workflow Setup
Cleanly set up CLAUDE.md, project conventions, and tool permissions for the team.
Agent Strategy
Build subagent and automation workflows for recurring development tasks.
Team Onboarding
Train developers in productive, safe use of AI coding assistants.
10. Summary
SAST-Style Security Reviews with Claude: The Essentials at a Glance
Core principle
Semgrep and SonarQube match code against known patterns, Claude traces the actual data flow across multiple files.
Biggest value add
Flawed authorization chains and business logic errors that classic scanners cannot structurally capture.
Recommended combination
Semgrep as a fast, deterministic gate on every commit, Claude as an in-depth review on pull requests.
Key limitation
No substitute for pentests, results vary slightly and are bounded by the context window.