Skip to content
AI|Course
← Analyze AI-Generated Code for Quality and Security

Lesson 2 of 7 · 1 hr 30 min

Reviewing by risk

Reading every line with equal care does not scale. Review AI-generated code by risk: spend your attention where mistakes are costly and where models are known to fail.

Watch

IBM's five practices for securing AI-generated code. A good companion to the risk-based review in this lesson.

Watch on YouTube (opens in a new tab)Video by IBM Technology. The player loads only when you press play.

Step 1: Review the intent before the code

  • What problem was this supposed to solve? Is the request written down (issue, ticket, prompt)?
  • Does the change do only that? AI diffs often sprawl: unrelated refactors, renamed files, reformatted code. Ask for a smaller change.
  • Is the approach reasonable, or did the tool pick a convoluted path because it was easy to generate?

Google's published engineering practices on code review are a good model for what a review should cover, from design and functionality to complexity, tests, naming, comments and style.

Step 2: Map the risk

Mark each changed area:

RiskExamplesHow closely to review
HighAuthentication, authorization, payments, cryptography, input parsing, file and network access, database queries, secrets, infrastructure codeLine by line, with a security-minded reviewer
MediumBusiness logic, data transformations, concurrency, error handlingRead carefully and test edge cases
LowFormatting, logging text, documentation, trivial glueSkim, rely on automation

Step 3: Hunt known failure patterns

A checklist tuned to AI-generated code:

  • Invented APIs and parameters. Does every called function, method and flag exist in the version you use? Check docs, not memory.
  • Unchecked trust boundaries. Is input from users, files, the network or other services validated before use?
  • Missing authorization. The code checks that you are logged in but not that you may access this record.
  • Swallowed errors. Broad except blocks that log and continue, returning success when something failed.
  • Weakened tests. Deleted assertions, loosened expectations, skipped tests or mocks that hide the real behavior.
  • Hard-coded values. Secrets, URLs, credentials or magic numbers.
  • Copy-paste duplication of logic that already exists elsewhere in the repo.
  • Plausible but wrong edge cases: empty input, null, off-by-one, time zones, Unicode, large inputs, concurrency.
  • Unnecessary dependencies added for something the standard library does.
  • Mismatch with project conventions, such as error types, logging, naming or layering.

A worked example

Which of these two would you approve?

# Version A (typical generated output)
def get_user(conn, email):
    return conn.execute(f"SELECT * FROM users WHERE email = '{email}'").fetchone()

# Version B
def get_user(conn, email):
    return conn.execute("SELECT * FROM users WHERE email = ?", (email,)).fetchone()

Version A builds the query by pasting user input into SQL, which allows SQL injection: an email of ' OR '1'='1 changes the query's meaning. Version B passes the value as a parameter, so the database never treats it as SQL. Both "work" in a happy-path test, which is exactly why you need a review habit and an automated check.

Step 4: Ask the author (or the tool) to explain

  • "Why this approach over the simpler one?"
  • "What happens with an empty list? A negative number? Two concurrent calls?"
  • "Which tests would fail if this line were wrong?"

If the author cannot explain the code, it is not ready to merge. Using an AI tool to explain code can help you review, but verify its explanation against the code, because explanations can be as confidently wrong as code.

Step 5: Run it

Check out the branch. Run the tests, run the feature, and try to break it: bad input, missing permissions, large inputs, failure of a dependency. Reading alone misses behavior.

Keep changes small

The best defense against unreviewable AI output is a policy of small, focused pull requests. If a change is too big to review properly, it is too big to merge.

Resources

DocsGoogle eng-practices
What to look for in a code review (opens in a new tab)

Google's public guidance on what reviewers should check.

DocsAbseil / Google
Software Engineering at Google, Chapter 9 (opens in a new tab)

The book chapter on code review: why teams do it and how it works at scale.

DocsOWASP
OWASP Cheat Sheet Series (opens in a new tab)

Concise, secure-coding guidance on queries, authentication, input handling and much more.

DocsOWASP
OWASP Application Security Verification Standard (opens in a new tab)

A detailed list of security requirements to review against.

Check yourself

  1. Take an AI-generated pull request and apply the five steps. Time each step.
  2. Write the failure-pattern checklist as a pull request template for your repo.
  3. Find one bug that reading alone missed but running the code revealed.

Found a broken link or a mistake? Report it (opens in a new tab).