Skip to main content
New aislop v0.13.1 patch — calibrates hidden-fallback detection and fixes regex comment-masker false positives. Read the changelog →
← Blog
Guide · 4 min read

AI Code Security Review Checklist: From Prompt to Production

Generated code inherits ordinary application risk and adds a new failure mode: plausible security decisions made without your threat model.

A coding agent does not know your threat model unless you provide it. Even then, it may satisfy the visible prompt while weakening a control elsewhere: move authorization into the client, log a token during debugging, invent a package, broaden a cloud permission, or convert a denied request into an empty success response.

Fluent code is not security evidence. Review generated changes as untrusted input to the software delivery process: useful, potentially correct, and not accepted until the relevant properties are proved.

Start with the change's threat surface

Identify assets, actors, entry points, trust boundaries, and the worst credible failure. A CSS change and a token exchange do not deserve the same review budget. Increase scrutiny when a patch touches identity, money, personal data, code execution, file access, infrastructure, dependencies, cryptography, or audit evidence.

Write this before review: “An attacker who controls ___ must not be able to ___, and we prove that with ___.”

1. Identity and authorization

  • Authentication is verified by the trusted server or identity provider, not a client flag.
  • Authorization is checked for the specific resource and action on every entry path.
  • Tenant, organization, and user identifiers come from trusted claims or verified mappings.
  • Default roles and permissions are least-privilege; wildcards and broad scopes are justified.
  • Session rotation, expiry, logout, replay, and revocation behavior are tested.
  • Error messages do not reveal whether a protected account or resource exists.

2. Input, data, and privacy

  • Untrusted input is parsed and constrained at the boundary before domain use.
  • Queries, templates, paths, headers, and redirects use safe APIs rather than string assembly.
  • Output is encoded for its destination context.
  • Uploads have type, size, storage, malware, access, and lifecycle controls.
  • Personal or regulated data has a defined purpose, retention period, and deletion path.
  • Test fixtures, prompts, logs, and analytics do not contain production secrets or personal data.

3. Execution and network boundaries

  • Shell commands avoid concatenating untrusted values and run with the minimum privileges.
  • File paths are normalized, constrained to an allowed root, and resistant to traversal.
  • Outbound requests restrict protocols, hosts, redirects, DNS behavior, and private-network access where relevant.
  • Every network call has timeout, cancellation, response-size, and retry limits.
  • Deserialization does not instantiate arbitrary types or execute code.
  • Agent tools and automation require confirmation for destructive or externally visible actions.

4. Dependencies and build integrity

OWASP warns that coding assistants can hallucinate plausible package names. If an attacker registers one of those names, an unverified install becomes a supply-chain entry point.

  • Every new package exists in the expected registry and has a real, consistent source repository.
  • Maintainer history, package age, release history, activity, downloads, and license are reviewed.
  • The dependency is necessary; the standard library or an approved package cannot do the job.
  • Lockfiles are updated intentionally and reviewed for unrelated transitive changes.
  • Install scripts, binaries, generated artifacts, and checksums are understood.
  • SCA, provenance, signing, and software-bill-of-material controls run where the risk requires them.

5. Secrets, errors, and observability

  • No secret is embedded in source, generated fixtures, prompts, URLs, or client bundles.
  • Errors preserve enough context for operators without exposing sensitive data to users.
  • Authentication, authorization, data export, configuration, and destructive actions create appropriate audit events.
  • Logs are structured, access-controlled, retained deliberately, and resistant to injection.
  • Fallback behavior is explicit; security failures do not silently become successful empty results.
  • Metrics and alerts reveal repeated denial, unexpected privilege use, and dependency or policy failures.

6. Tests and delivery controls

  • A negative test proves an unauthorized actor cannot perform the action.
  • Boundary fuzzing or property tests cover malformed and adversarial input where valuable.
  • Security tests fail if the new control is removed.
  • The patch does not delete, skip, weaken, or broadly mock the check it is meant to satisfy.
  • Deployment uses least-privilege credentials and has a tested rollback or containment path.
  • High-risk findings cannot be suppressed without an owner, reason, expiry, and review.

AI-specific review questions

  • Which APIs, packages, configuration keys, and claims were independently verified against primary documentation?
  • Did the agent modify security controls, tests, permissions, or error handling while pursuing a green build?
  • Are there speculative fallbacks or compatibility paths the task never required?
  • Does a confident comment describe behavior the code does not enforce?
  • Did the agent copy a security pattern from a different framework version or trust model?
  • Can the author explain the exploit the control prevents and the evidence that it works?

Automate in layers

Use the compiler and type system, behavioral tests, SAST such as CodeQL, secret scanning, dependency analysis, infrastructure policy, and runtime validation. Add a deterministic generated-code scan for patterns that often hide failures: swallowed exceptions, unsafe type escapes, debug output, unresolved stubs, dead code, vulnerable dependencies, and complexity.

npx aislop@latest scan --changes

aislop is one quality layer, not a security certification. It should make repeatable problems visible before a security reviewer spends time on threat modeling and exploitability.

The merge rule

Merge only when the team can name the trust boundary, show evidence for the relevant security properties, independently verify external artifacts, and assign a human owner to the remaining risk. “The agent said it is secure” is not evidence. Neither is “the scanner was green” when the threat model was never encoded in the scanner.

Sources

Frequently asked questions

Is AI-generated code less secure than human-written code?

Security depends on the task, model, context, controls, and verification. AI-generated code can introduce ordinary vulnerabilities plus AI-specific mistakes such as hallucinated dependencies, invented APIs, weakened tests, and confident assumptions about trust boundaries. Treat it as untrusted until verified.

What should I check before merging AI-generated code?

Verify identity and authorization, input and data handling, command and network execution, dependencies and build integrity, secrets and logging, failure behavior, deployment controls, and test coverage. Independently verify every external package and API.

Can a static scanner secure AI-generated code?

No single scanner is sufficient. Combine compiler and type checks, tests, SAST, secrets and dependency scanning, generated-code quality rules, runtime or integration testing, and human threat-model review for consequential boundaries.