Skip to content

Preface - Why Security Code Review Skill Still Matters in the Age of AI

Preface - Why Security Code Review Skill Still Matters in the Age of AI

Software is the centerpiece of the internet age, and it will be the foundation of the AI era.

AI-assisted coding changes who can create software. It also changes how fast they can create it. More code is now produced by more people, including non-traditional and less experienced programmers.

This creates a security problem. When more code is written faster, with uneven security knowledge, more insecure code will be produced. Security has to change with the process.

Security code review still has the same function. It examines implementation and removes insecure code before it becomes production risk. But the role of security engineering must expand.

Security engineers cannot only review code after it is generated. They also need to help prevent bad code from being generated in the first place. Secure coding needs to be built into the code generation process. Security engineers still review the resulting code, but they must do it at larger scale and faster pace.

The New Code Production Reality

AI-assisted coding changes the economics of software creation. It reduces the distance between an idea and a working implementation. It also reduces the distance between an insecure idea and a working implementation.

The risk is not only that AI may generate a vulnerable snippet. The larger risk is over-dependence: teams may trust generated code because it compiles, passes a quick test, or looks idiomatic. But working code is not the same thing as secure code.

AI-assisted coding systems are trained on large bodies of existing code. Public code contains many insecure patterns. There is far more ordinary, incomplete, outdated, tutorial-style, copied, and vulnerable code than carefully reviewed secure code.

That means generated code can reproduce familiar mistakes with confident syntax:

  • string-built SQL queries instead of parameterized statements
  • raw output rendering instead of output encoding
  • path construction from user input
  • weak session or cookie handling
  • hardcoded secrets and debug bypasses
  • denylist-based filtering where allowlists or stronger design controls are needed

For security engineers, this creates a new challenge. The problem is no longer only "Can I review this code?" It is also "Can I review enough code, fast enough, with enough context, and still produce accurate security judgment?"

This book is about that challenge.

Why Classic Security Code Review Still Matters

Security code review is a specialized form of analysis. It asks whether implementation behavior can be abused. It does not stop at asking whether implementation behavior works.

Functional review asks questions such as:

  • Does the feature do what the ticket requested?
  • Is the code readable?
  • Are edge cases handled?
  • Do tests pass?

Security review asks a different set of questions:

  • Who controls this input?
  • What trust boundary does it cross?
  • What authority does this code execute with?
  • Is authentication being confused with authorization?
  • Could this behavior expose data, change state, or execute attacker-controlled logic?
  • What assumption would need to be false for this code to become dangerous?

These questions are old, but they are not obsolete. AI-assisted development makes them more important because generated code can be syntactically clean while preserving insecure assumptions.

Consider the classic SQL injection pattern from the reference article:

sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"

The code is easy to understand. It may even work in a demo. But it mixes query structure with attacker-controlled input.

The secure pattern separates code from data:

String query = "SELECT * FROM User WHERE username = ? AND password = ?";

PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, username);
statement.setString(2, passwordHash);

resultSet = statement.executeQuery();

This is a classic lesson, but it remains relevant in AI-generated code. A model can produce either pattern. The reviewer still needs to know which one preserves the security boundary.

From Classic Review to AI-Assisted Security Review

This mini-book has two goals. First, it reviews classic security code review techniques. Then it shows how security engineers can use AI-assisted review in a scalable and accurate way.

Classic review techniques still provide the foundation:

  • input validation and parsing
  • output encoding
  • authentication and authorization review
  • session management review
  • injection analysis
  • file and path handling review
  • secure logging
  • secret management
  • dependency and framework configuration review
  • secure-by-default implementation checks

AI can help with this work, but it should not replace the underlying reasoning. Used well, AI can help a security engineer summarize a codebase and generate review checklists. It can also identify suspicious data flows, map patterns to vulnerability classes, explain unfamiliar code, and compare a proposed fix against secure coding principles.

For a small codebase, AI-assisted review can help a security engineer move faster. It can summarize the feature, identify likely trust boundaries, generate review questions, and focus attention on high-risk functions.

For a large codebase, AI-assisted review can help manage scale. It can summarize modules, cluster risky patterns, find repeated anti-patterns, connect related code paths, and help prioritize review depth.

But accuracy still depends on human validation. The reviewer must verify evidence, confirm exploitability, understand business context, and decide whether a finding is real. AI can reduce review friction, but it cannot remove the need for security judgment.

Working Code Is Not Necessarily Secure Code

Many security issues come from code that behaves exactly as the developer intended. The problem is that the intent did not include the attacker.

Stored and reflected XSS are examples of this problem. A page can correctly retrieve a username and display it back to the user. It can still fail to encode output safely.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    User user = databaseManager.getUserFromId(request.getParameter("id"));
    request.setAttribute("user", user.getUsername());
    doForward(request, response);
}

If the value is rendered directly in the page, functional behavior and insecure behavior can look identical during normal testing:

<div id="hello-message">
    <p>Hello user <%=request.getAttribute("user")%>. Welcome to the platform!</p>
</div>

The secure review question is not only "Does this display the username?" It is also "What happens if the username contains markup or script content?" The reviewer also needs to ask where output encoding is enforced.

The reference article shows the safer JSP/JSTL pattern:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div id="hello-message">
    <p>Hello user <c:out value="${requestScope.user}" />. Welcome to the platform!</p>
</div>

This is the kind of difference security review is designed to catch. The vulnerable and secure versions may be close in size, style, and apparent complexity. The important difference is the security property.

The same principle appears in small shortcuts. A debug bypass password may be only one line:

        optionalUser.ifPresent(user -> {
            if (this.bCryptUtils.checkPasswordHash(password, user.getPassword()) || "byp@33_p@ssw0rd".equals(password)) {
                HttpSession session = req.getSession();
                session.invalidate();
                // ...

This is not a complex algorithmic flaw. It is a simple implementation decision with a serious security consequence. A reviewer must notice that small shortcuts are not harmless.

Why AI Changes the Stakes

AI-assisted coding increases both productivity and ambiguity.

It can produce a working implementation quickly. But the reviewer may not know where the generated code pattern came from. It may come from a secure pattern, an outdated tutorial, or an unsafe mix of examples.

The code may look clean. The comments may sound reasonable. The function names may be polished. None of that proves the implementation is safe.

Some vulnerability classes are especially important in this environment because they require reasoning about attacker-controlled input and trust boundaries.

For example, command injection appears when user-controlled data reaches an external command:

String[] cmd = { "/bin/sh", "-c", 'ping '+hostname };
Process p = Runtime.getRuntime().exec(cmd);

SSRF appears when user-controlled input influences a server-side request:

URL url = new URL("http://127.0.0.1" + endpoint);
StringBuilder result = new StringBuilder();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
    for (String line; (line = reader.readLine()) != null;) {
        result.append(line);
    }
}

The issue is not simply the API call. The issue is the relationship between input, authority, and reachable resources. If endpoint is attacker-controlled, the server may become a bridge into internal services:

POST data: {"endpoint" : "/users/1"}
# Result: '{"username" : "user"}'

Attackers can control the endpoint data in the POST request to access endpoints otherwise blocked by external hosts.
POST data: {"endpoint" : "/secret"}
# Result: '{"secret_key" : "a092fb8ab2c2"}'

This is where AI assistance can help and mislead. AI may identify the pattern. It may also suggest a denylist, miss an internal trust boundary, or fail to understand which endpoints should be reachable.

Human review remains responsible for the final security judgment.

The Three Layers of This Book

This book progresses through three layers.

The first layer is theory. It defines security code review and explains how it differs from general code review. It also introduces the mental models that make review systematic: uncertainty reduction, threat-oriented thinking, trust boundaries, attack surface, and defensible confidence.

The second layer is practice. It moves from broad methodology into concrete review work: manual review, code-level analysis, dependency review, automation, and AI-assisted workflows. The goal is not only to list vulnerability classes. It is to show how a reviewer thinks from system behavior down to implementation details.

The third layer is training. Security code review is a skill that improves through repeated exposure to real patterns. The later chapters discuss how to build reviewer capability with vulnerable examples, secure patches, structured exercises, AI-assisted workflows, and internal review programs.

The book is written for security engineers, AppSec engineers, security champions, software engineers who care about secure implementation, and teams trying to make review more scalable without making it shallow.

The Core Outcome: Defensible Confidence

The objective is not perfection.

Perfect security review is not realistic for modern software systems. Codebases are too large. Dependencies are too deep. Delivery cycles are too fast. Implementation context changes too often.

The objective is defensible confidence.

Defensible confidence means the reviewer can explain the review. They can say what was reviewed, why it mattered, what assumptions were tested, what evidence was found, and what risk remains. It turns vague assurance into structured judgment.

That is why security code review matters in the age of AI. AI can generate code faster than organizations can manually inspect every line. The answer is not to abandon review. The answer is to make review more systematic, more evidence-driven, and more scalable.

Security code review is no longer only about finding bugs in human-written code. It is about validating software behavior in an environment where code may be generated, copied, remixed, accelerated, and deployed faster than ever before.

How to Read This Mini-Book

Read the early chapters as the foundation: terminology, principles, and mental models.

Read the middle chapters as practice. They show how to move from system understanding to specific review targets. They also show how to reason about vulnerabilities and combine manual and automated techniques.

Read the AI chapters as operating guidance. They explain where AI can accelerate review, where it can fail, and how security engineers can keep human judgment in the loop.

Read the training chapters as a way to scale the skill across a team.

The purpose of this book is not to make every reader a perfect reviewer. The purpose is to make security review more explainable, repeatable, and useful. That matters more as software creation becomes faster, broader, and more AI-assisted.