Guides
Detection guide

Code Security Scanning: Catch Risky Code in New Commits

By Sazabi Team

Last verified on Nov 8, 2026.

Most serious vulnerabilities are introduced in a single commit by someone who did not mean to. A new endpoint ships without an authorization check. A refactor moves a guard behind a branch that is not always taken. A query is built from a string. Review catches some of these. The rest reach production, where they are found by an attacker or an audit months later.

Code security scanning moves detection to the commit, which is the cheapest place to fix. This guide covers how to scan new code for the classes of risk that matter most, how to read the results and how to keep a scanner useful instead of ignored.

What the evidence looks like

The evidence is a finding tied to a change: a rule, a file and line, a severity and the commit or pull request that introduced it. A missing authorization check is the standard example, and it maps to a named weakness. MITRE's CWE-862, Missing Authorization, covers software that does not perform an authorization check when an actor attempts to access a resource or perform an action. OWASP puts Broken Access Control first in its 2021 Top 10.

An example of a finding as a scanner reports it:

{
  "rule": "route-without-auth-middleware",
  "severity": "high",
  "file": "src/routes/invoices.ts",
  "line": 42,
  "commit": "a91c3f0",
  "message": "Route registered without requireAuth"
}

And the diff that caused it, as an example:

+ router.get('/api/invoices/:id', async (req, res) => {
+   res.json(await db.invoices.find(req.params.id))
+ })

Authentication bypasses, injection through string-built queries and unsafe deserialization show up the same way: a pattern in the new lines that a rule matches.

How to detect it step by step

1. Scan on every pull request. Run a static analyzer against the changed files and fail the check on new high-severity findings. GitHub documents CodeQL for code scanning, and Semgrep provides a rule-based scanner with community and custom rules. Both fit into CI. Use whichever fits your languages.

2. Write rules for your own conventions. Generic rules find generic bugs. The ones that find your bugs encode how your code is supposed to work. Semgrep rules support operators such as pattern, pattern-not and metavariable-regex, and a severity of low, medium, high or critical. A sketch for a route that lacks your auth middleware:

rules:
  - id: route-without-auth-middleware
    languages: [typescript]
    severity: HIGH
    message: Route registered without requireAuth. Add it or mark the route public.
    patterns:
      - pattern: $ROUTER.$METHOD($PATH, async ($REQ, $RES) => {...})
      - pattern-not: $ROUTER.$METHOD($PATH, requireAuth, async ($REQ, $RES) => {...})
      - metavariable-regex:
          metavariable: $METHOD
          regex: ^(get|post|put|patch|delete)$

3. Store results in a common format. SARIF, the OASIS Static Analysis Results Interchange Format, is a standard for static analysis output. Keeping findings as SARIF means you can merge results from several tools and track them over time.

4. Track findings per commit. Record each finding with its first-seen commit, author and status. This is the evidence trail: "introduced Tuesday in commit a91c3f0, fixed Thursday".

5. Pair it with runtime signals. A route flagged as missing a check that also receives traffic from many actors is more urgent than one behind a feature flag. The access log queries in the access anomalies guide are the runtime half.

Thresholds and pitfalls

Gate on new findings only. Run a baseline once, record existing findings as accepted, and block only on what a change adds. Otherwise the first scan produces thousands of results and the team turns the check off.

Common problems:

  • False positives. Static analysis cannot know that a route is public by design. Offer a marker, such as an explicit public() wrapper, so the rule has something to see.
  • False negatives. Scanners find syntactic patterns. Logic flaws, such as checking that a user is logged in but not that a record is theirs, mostly slip through. Pair scanning with tests for authorization.
  • Severity drift. If everything is high, nothing is. Reserve high for findings you would block a release over.
  • Slow scans. A check that takes 20 minutes gets skipped. Scan the diff on pull requests and the whole repository nightly.
  • Generated and vendored code. Exclude it, or findings you cannot fix will bury those you can.

What to do when it fires

Treat a high-severity finding like a failing test: fix it in the pull request. If it is a true positive in code that already shipped, check the access logs to see whether the route was reached before you fixed it, and by whom. If it is a false positive, adjust the rule or add a narrow, commented suppression rather than disabling the check.

Review what the scanner has not learned yet. Every vulnerability found by a person, a customer or a pentest should become a rule, so the same mistake is caught next time. Related: supply chain attacks covers risk in dependencies rather than your own code, new advisories covers known vulnerabilities in what you use, and exposure covers what is reachable from outside. See the GitHub and CodeRabbit integrations for review-time signals.

Frequently Asked Questions

What is code security scanning?

It is automated analysis of source code for security flaws such as missing authorization checks, injection risks and unsafe functions. It runs on commits or pull requests so problems are fixed before release.

How do I stop a scanner from creating too much noise?

Record existing findings as a baseline and block only on new high-severity findings in the diff. Reserve the high severity for issues you would delay a release for.

Can static analysis find missing authorization checks?

Only when the pattern is visible in the code, for example a route registered without your auth middleware. Logic flaws like checking login but not record ownership need tests as well.

What format should scanner results use?

SARIF is an OASIS standard format for static analysis results, so results from different tools can be merged and tracked over time.

Sources

  1. CWE-862 Missing Authorization: software does not perform an authorization check when an actor attempts to access a resource or perform an action (accessed Nov 8, 2026)
  2. Broken Access Control is ranked first in the OWASP Top 10 2021 (accessed Nov 8, 2026)
  3. Code scanning with CodeQL (accessed Nov 8, 2026)
  4. Semgrep rule syntax: pattern operators, pattern-not, metavariable-regex and severity levels (accessed Nov 8, 2026)
  5. SARIF 2.1.0, the OASIS standard format for static analysis results (accessed Nov 8, 2026)