SecurityBlog Post

Code Audit Checklist: What a Professional Code Audit Covers, With an Example Finding

What is a code audit, what should it check, and what should the report look like? A practical checklist covering security, data access, payments, reliability, and maintainability, plus an example of an actionable finding and how to prepare.

By Abhay Mittal

9 min read
Code Audit Checklist: What a Professional Code Audit Covers, With an Example Finding
Is your AI-built app exposed? Get a professional vibe coding audit and ship to production with confidence.

A code audit is a structured review of an application's source code, configuration, and architecture to find security vulnerabilities, reliability problems, and maintainability risks before they cause damage. It is different from a quick code review on a pull request. An audit looks at the whole system, with a defined scope, and produces a written report you can act on.

This guide explains what a professional code audit covers, gives you a checklist you can use yourself, shows what a useful finding looks like, and explains how to prepare. It is written for founders and small teams, especially those with codebases built quickly using AI tools.


What is code auditing?

Code auditing means systematically examining code against a set of expectations: that it is secure, that it does what the business needs, that it handles failure, and that someone other than the original author can maintain it.

A good audit combines three activities:

  1. Automated analysis to find known-dangerous patterns, vulnerable dependencies, and leaked secrets quickly.
  2. Manual code review of the flows that matter most: authentication, authorization, payments, data handling, and any AI or agent features.
  3. Targeted testing in a safe environment to confirm that suspected issues are real and to show how they can be reproduced.

The output is not a list of scanner warnings. It is a prioritised set of confirmed findings, each explaining the impact, how to reproduce it, how to fix it, and how to verify the fix.


When you need a code audit

Common triggers include:

  • Before a public launch or before taking real payments.
  • Before onboarding an enterprise customer who will send a security questionnaire.
  • During a fundraise, acquisition, or other technical due diligence.
  • After building quickly with AI coding tools, when nobody has read all of the code.
  • After a security incident or a near miss.

The code audit checklist

Use this as a checklist for your own review or to evaluate what an auditor proposes to cover. The OWASP Application Security Verification Standard (ASVS) is a much more detailed reference if you want depth.

1. Scope and architecture

  • Which repositories, services, and environments are in scope?
  • How does data flow between front end, API, database, and third-party services?
  • Where are the trust boundaries: what runs in the browser, what runs on the server, and what talks directly to the database?
  • Which flows carry the most business risk (sign-up, payments, data export, admin tools)?

2. Authentication

  • Passwords are hashed with a modern algorithm, or authentication is delegated to a trusted provider.
  • Sessions and tokens expire, and logout invalidates them.
  • Password reset and email verification tokens are single-use and time-limited.
  • Login, OTP, and reset endpoints are rate limited.
  • JWT signing secrets are strong and stored securely. See the JWT secret AI tools love to hardcode.

3. Authorization and data access

  • Every API route and server action checks both identity and permission for the specific record.
  • Users cannot read, change, or delete other users' data by changing an ID. See the IDOR bug in AI-generated API routes.
  • Multi-tenant boundaries (teams, organisations, workspaces) are enforced in queries or database policies, not just in the UI.
  • Role checks for admin actions happen on the server.
  • Database policies, such as Supabase row-level security, are enabled and correct. See Supabase row-level security.

4. Input handling

  • Queries are parameterised; no SQL or NoSQL built from user input.
  • User content is escaped before rendering, and raw HTML rendering is avoided or sanitised.
  • File uploads are validated by type and size and stored outside public paths unless intentionally public.
  • Server-side requests to user-supplied URLs are restricted to prevent SSRF.

5. Secrets and configuration

  • No secrets in source code or git history.
  • No secret values exposed to the browser through public environment variables.
  • Separate credentials for development, staging, and production.
  • Security headers, CORS, and cookie settings are deliberate. See CORS and cookie authentication risks.

6. Payments and business logic

  • Prices, discounts, and plan limits are determined on the server. See checkout price tampering.
  • Paid access is granted only after a verified webhook. See Stripe webhook signature bypass.
  • Cancellations, refunds, failed renewals, and downgrades behave correctly.
  • Multi-step flows cannot be skipped or replayed to gain value.

7. AI and agent features

  • User input cannot redirect the model into revealing system prompts or other users' data.
  • Tools an AI agent can call are limited to what the current user is allowed to do.
  • AI usage is rate limited to prevent runaway cost.
  • Model output is treated as untrusted before it is rendered or executed.

If your product is built around agents or MCP, an AI agent security audit goes much deeper here.

8. Dependencies and supply chain

  • Dependencies are pinned through a lockfile and checked for known vulnerabilities.
  • Packages are real, maintained, and necessary.
  • CI/CD secrets and build scripts are reviewed for exposure.

Our supply chain security audit covers this area in detail.

9. Reliability and operations

  • Errors are handled without leaking stack traces or internal details.
  • Logging captures security-relevant events without logging secrets or personal data.
  • Backups exist and have been restored at least once.
  • List endpoints paginate, and expensive operations have limits.

10. Maintainability

  • The code is organised so a new developer can find where things happen.
  • Critical flows have tests, including negative tests for access control.
  • Duplicated or dead code from AI iteration is identified for cleanup.

What a code audit report should contain

A useful code audit report has:

  • An executive summary in plain language: overall risk, the most important findings, and what to fix first.
  • Scope and method: what was reviewed, what was not, and how.
  • Findings, each with a severity rating, affected components, impact, reproduction steps, a recommended fix, and how to verify it.
  • Positive observations, so you know what is already done well and should be preserved.
  • Recommendations for process improvements, such as tests or CI checks, to prevent recurrence.

A report that lists hundreds of unconfirmed scanner warnings without context is not an audit report. It is a scanner export.


Code audit example: what a good finding looks like

Here is an illustrative finding in the format we use. It is an example of structure, not a result from a client engagement.

Finding: One account can read another account's invoice

Severity: High

Affected flow and impact: The invoice endpoint checks that a user is logged in but does not check who owns the invoice. A second user can read private billing data by changing the invoice ID in the request.

Reproduction: In an authorised test environment, create accounts A and B. Create an invoice as A. While signed in as B, request A's invoice endpoint. The vulnerable response returns A's invoice.

Recommended fix: Scope the database query to the authenticated account or tenant on the server, for example by filtering on both the invoice ID and the owner ID. Apply the same ownership check to read, update, download, and delete routes for invoices.

Verification: Confirm B receives a 403 or 404 for A's invoice, logged-out requests are rejected, and A can still read it. Add an automated regression test for cross-account access.

Every finding should be this concrete. If you cannot reproduce it from the report, or cannot tell when it is fixed, the finding is not finished.


How to audit code yourself

If you are not ready for a professional audit, you can get real value from a structured self-review:

  1. Write down your roles and what each one may access.
  2. Run automated tools: secret scanning, dependency checks, and static analysis. Our guide to the best vibe coding security tools covers free options.
  3. Walk through the checklist above, starting with authorization and payments.
  4. Run the two-account access test described in how to test vibe-coded apps.
  5. Record each issue in the finding format above, then fix and verify.

For AI-built apps specifically, our how to review vibe-coded apps guide adds checks for patterns AI tools commonly introduce.


How to prepare for a professional code audit

You will get more from an audit, faster, if you prepare:

  • Give access to the repository and a staging environment with test accounts for each role. Never share production user data.
  • Write a short overview: what the app does, the stack, the main user roles, and third-party services.
  • List your concerns: flows you are unsure about, recent incidents, or customer questions you need to answer.
  • Agree on scope in writing: which repositories, which flows, and whether retesting after fixes is included.
  • Freeze major changes during the review where possible, so findings stay accurate.

Our code audit service follows this structure, and the pricing page explains how scope affects cost. If you want a quick view of where you stand first, try the free vibe code security check.


FAQ

What is the difference between a code audit and a code review?

A code review usually checks a specific change before it merges. A code audit examines the whole application, or a defined part of it, against security, reliability, and maintainability expectations, and produces a formal report.

How long does a code audit take?

It depends on the size of the codebase and the scope. A focused review of a small app can take a few days; a multi-service platform takes longer. Scope, not hourly effort, should drive the estimate.

Is a code audit the same as a penetration test?

No. A code audit reads the source code and configuration. A penetration test attacks the running application from the outside. They find overlapping but different issues, and many teams benefit from both.

What does a code audit include?

Typically architecture review, authentication and authorization, input handling, secrets and configuration, payments and business logic, dependencies, reliability, and maintainability, delivered as prioritised findings with reproduction and fix guidance.

Can AI tools audit my code?

They are a useful first pass and catch many pattern-based issues. They do not know your intended business rules, so authorization and logic flaws often require human review.

Keep reviewing your app

Practical checks for the parts of an AI-built app that handle real users and money.

Need a second pair of eyes? Explore our code audit services, scope and pricing, and client case studies.

VibeAudits

Security Experts

Worried your vibe-coded app has issues like this?

We run professional code audits for SaaS apps and AI features built with Cursor, Claude, Copilot, Lovable and Replit. We find the security and reliability problems before your customers (or attackers) do, then hand you a fix-ready report.