Safeguard
Security

How to Run an Application Security Code Review That Catches Real Bugs

An application security code review is a targeted read of code for security defects. Here is a practical process that finds real issues without drowning in noise.

Priya Mehta
Security Analyst
6 min read

An application security code review is a focused examination of source code with one goal: find the defects an attacker could exploit before they ship. It is not the same as a general code review that checks style and readability, and it is not the same as running a scanner and calling it done. A good application security code review combines human judgment about how the software is supposed to behave with tooling that handles scale, and it is one of the highest-value activities a security-conscious team can build into its workflow.

This guide lays out a process you can actually follow, the defect classes worth hunting, and how to keep the review from becoming a wall of noise nobody reads.

Start with context, not code

The most common mistake is opening a diff and reading top to bottom. Without context you will spend your budget on trivia and miss the one function that matters. Before reading a line, answer three questions:

What does this code do, and what would an attacker want from it? A payment flow, an authentication path, and a file-upload handler each attract different attacks. What are the trust boundaries? Every place data crosses from untrusted to trusted, an HTTP request entering a handler, a message coming off a queue, a file being parsed, is where bugs concentrate. And what changed? For an ongoing review, the diff is your map. New input handling and new external calls deserve the most attention.

A lightweight threat model, even ten minutes on a whiteboard, pays for itself here. It tells you where to point the expensive human attention.

Follow the data

Once you know the trust boundaries, trace untrusted data from where it enters to where it is used. This data-flow reading is the core technique of security review because most serious vulnerabilities are a failure to validate, encode, or contain input somewhere along that path.

Follow a request parameter and ask at each hop: is it validated? When it reaches a query, is the query parameterized or concatenated? When it reaches a template, is output encoding applied for the right context? When it becomes a file path, can it escape the intended directory? When it is deserialized, is the type restricted? The vulnerability is almost always at the sink, the moment the data is used, but understanding requires the whole path.

The defect classes worth hunting

You cannot check for everything, so prioritize the categories that cause real damage. The OWASP Top 10 is a sensible backbone. In practice, these earn their place in every review:

Injection. SQL, command, LDAP, and template injection all share a root cause: untrusted data interpreted as code. Look for string concatenation feeding an interpreter.

Broken access control. Does the code check that the current user is allowed to act on the requested object, not just that they are logged in? Missing object-level authorization is one of the most common and most damaging findings, and scanners are weak at it because it depends on intent.

Authentication and session handling. Password storage, token generation, session fixation, and logout behavior. These are easy to get subtly wrong.

Secrets in code. Hardcoded API keys, credentials, and private keys. A quick automated pass catches most, but review still surfaces the clever ones assembled at runtime.

Cryptographic misuse. Weak algorithms, static IVs, ECB mode, home-grown crypto. The tell is usually someone using a low-level primitive when a high-level library would have been safer.

Where tools fit

Human review does not scale to a large codebase on every commit, and it should not try to. Automation handles breadth; humans handle depth.

Static analysis (SAST) reads code without running it and traces taint from source to sink. It is strong on injection and on mechanical patterns, and weak on business logic and authorization, because those depend on intent the scanner cannot infer. Software composition analysis is a separate concern: most of a modern application is third-party code, and an SCA scanner tells you when a dependency you pulled in, often transitively, carries a known vulnerability that no amount of reviewing your own code would reveal.

The practical division of labor is to let tools flag the mechanical issues and the known-vulnerable dependencies, and reserve human review for logic, authorization, and the design questions machines cannot answer. A finding a scanner produces still needs a human to judge exploitability in context, but the scanner ensures you are not manually hunting for a MD5 call across two thousand files.

Keep the output actionable

A review that produces a hundred findings of mixed severity gets ignored. Rank by real risk: exploitability times impact, in this application, with this deployment. A theoretical issue in dead code is not the same as an injection in the login path. For each finding, give the developer a location, a concrete explanation of the attack, and a specific fix or a link to a safe pattern. "Potential XSS" helps nobody. "This value is written into an HTML attribute without encoding; use the framework's attribute encoder here" gets fixed.

Feed recurring findings back into the process. If the same bug class keeps appearing, the answer is not more review, it is a safer default, a lint rule, or a shared library that makes the wrong thing hard to write.

Build it into the workflow

The best application security code review is the one that happens consistently. Wire SAST and SCA into pull requests so mechanical checks run automatically, reserve human security review for high-risk changes flagged by your threat model, and do periodic deeper reviews of critical components on a schedule rather than only after an incident. Reviewing every line of every commit by hand is neither possible nor useful; reviewing the right lines at the right time is.

FAQ

How is a security code review different from a normal code review?

A normal code review focuses on correctness, readability, and maintainability. A security code review specifically hunts for exploitable defects, tracing untrusted data to dangerous sinks and checking authorization and cryptographic decisions. The mindset is adversarial rather than collaborative.

Can I just run a SAST tool instead?

No. SAST is essential for scale and catches mechanical issues well, but it misses business-logic flaws and authorization gaps that depend on how the application is meant to behave. Tools and humans cover different classes of defect, so you need both.

How long should a security code review take?

It scales with risk, not line count. A high-risk payment or authentication change might warrant hours of focused reading, while a low-risk internal change needs only automated checks. Spend your human budget where a threat model says it matters.

What is the single highest-value thing to check?

Access control. Missing object-level authorization is both extremely common and extremely damaging, and it is precisely the class automated tools are worst at. If you review one thing, confirm the code verifies the user is allowed to act on the specific resource requested.

Never miss an update

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