Code audit services: what a source code audit covers
What a source code audit covers, how a good one is run, what the report should contain, and how to choose between code audit services before you sign.
Asghar Ali · Chief Technology Officer, Kakushin.io LTD
A source code audit is an independent, time-boxed reading of a codebase by someone who did not write it, ending in a written report of what is wrong, how much it matters and how to fix it. Code audit services sell exactly that: a fixed scope, a senior reader, automated scans plus a manual pass, and a prioritised list of findings you can act on.
That is the short answer. The longer one matters more if you are about to pay for an audit, because two engagements with the same name can deliver very different things. One is a scanner's output with a cover page. The other is a person who has read the code that handles your money, your permissions and your data, and can tell you which three problems to fix this week.
This is how I scope and run a code review of someone else's system, written for the person commissioning it.
What is a source code audit, and how is it different from a code review?
A code audit looks at the whole codebase at a point in time, from outside the team, and reports to whoever commissioned it. A code review looks at one change, from inside the team, before it merges. They use the same skill but answer different questions.
The word "audit" is also used for things that are not about code quality at all, which is the first source of confusion when you search for one:
| Engagement | What it reads | The question it answers | Who usually asks |
|---|---|---|---|
| Source code audit | The repository, its history, its build and its dependencies | Is this code safe, maintainable and fit for what it will be asked to do? | Founders, CTOs, buyers, a new owner |
| Code review | One pull request | Should this change merge? | The team, every day |
| Penetration test | The running system, from outside | Can an attacker get in, given what is deployed? | Security and compliance |
| Technical due diligence | Code, team, infrastructure, costs and rights | What will it cost to own this, and should the deal go ahead? | Investors and acquirers |
| Software (licence) audit | Installed software and licence entitlements | Are we paying for what we use? | Finance and procurement |
A source code audit sits between a penetration test and due diligence. It goes deeper into the code than a pen test can, because it reads the logic rather than probing it, and narrower than due diligence, because it does not assess the team or the deal. If you are buying a company, what technical due diligence actually looks at covers the wider review; an audit is often one part of it.
What a code audit covers
A complete audit reads seven areas. Security is usually the reason someone calls, but the findings that cost the most over a year are often in the other six.
| Area | What gets read | A typical finding |
|---|---|---|
| Security | Authentication, authorisation, input handling, secrets, cryptography, file and URL handling | An API returns another customer's record when you change the ID in the request |
| Architecture | Module boundaries, data model, integrations, where state lives | Business rules duplicated in the app and the API, already disagreeing |
| Maintainability | Size and complexity hotspots, duplication, naming, dead code | One file that is both the largest and the most frequently changed |
| Dependencies and licences | Lockfiles, versions, known vulnerabilities, licence terms | A library with a published critical vulnerability and an available fix, two major versions behind |
| Tests and delivery | Test coverage of critical paths, CI pipeline, release process | Tests pass, but none touch payments or permissions |
| Performance and scale | Queries, caching, background work, external calls in loops | A list page that runs one database query per row |
| Operability | Logging, error handling, configuration, backups, the README | Nobody can build the project from a clean machine by following the docs |
For security, I read against a recognised standard rather than from memory: the OWASP Application Security Verification Standard for what a control should do, the OWASP Code Review Guide for how to look for it, and the CWE Top 25 to name weaknesses in a way another engineer can look up. Maintainability findings map loosely onto the quality characteristics in ISO/IEC 25010, which is useful mainly because it gives the report shared vocabulary.
If the code was largely produced with an AI assistant, the security pass shifts its weight. The holes are predictable, and I listed them in the security risks nobody checks in vibe-coded apps.
How a source code audit is run
A good audit is a sequence of seven steps. The automated part takes a fraction of the time; the manual reading is where the value is.
1. Agree the scope and the questions
Before any code is shared, write down which repositories are in scope, which are not, and the two or three questions the audit must answer. "Is it safe to launch to paying customers?" leads to a different reading from "Can a new team take this over?" A fixed scope is what makes a fixed price possible.
2. Take read-only access, and plan to give it back
Read access to the repository, the CI configuration, and a description of how production is deployed. No production credentials and no customer data are needed for a source code audit. Agree up front when access will be revoked, and sign the NDA before anything is shared.
3. Run the automated pass
This takes hours, not days, and tells the reader where to spend the rest. On a typical JavaScript or TypeScript codebase I start with:
# Secrets anywhere in history, not just the current files
gitleaks git -v .
# Known vulnerabilities in dependencies, from the lockfiles
osv-scanner scan source -r .
# Static analysis with community rules
semgrep scan --config auto
# Where the code is big and complex
scc --by-file --sort complexity . | head -30
# Where the code changes most often
git log --since="12 months ago" --name-only --pretty=format: \
| grep -v '^$' | sort | uniq -c | sort -nr | head -20
Each of these produces false positives, and none of them understands your business rules. Their output is a list of places to read, not a list of findings. An audit report that is mostly scanner output has skipped the expensive part.
4. Read the critical paths by hand
The manual pass follows the data that matters: sign-in and session handling, every endpoint that takes an ID, payments and refunds, file uploads, admin actions, anything that sends email or messages on a user's behalf, and every place a secret is used. The files that are both large and frequently changed get read in full.
The single most productive check is still the one from the application security best practices I enforce: for every request that reads or changes data, does the server confirm that this user may touch this object? Scanners almost never find a missing authorisation check. A reader with two test accounts finds it in an afternoon.
5. Write the findings so they can be fixed
Every finding gets the same structure. Here is an illustrative example of the format, not one from a real engagement:
F-03 · High · Effort: small
Invoice endpoint does not check ownership.
Where:
api/invoices/[id].ts, lines 12–19.Evidence: the lookup filters by
idonly. Signed in as a user of organisation A, a request for an invoice ID belonging to organisation B returns it.Impact: any signed-in user can read any customer's invoices, including names, addresses and amounts.
Fix: scope the query by the organisation from the session, return 404 when nothing matches, and add a two-account test for every object endpoint.
A finding without a location, evidence and a concrete fix is an opinion. A finding without an effort estimate cannot be planned.
6. Walk the team through it
A report read alone gets argued with or ignored. An hour with the engineers, going through the high-severity findings and the reasoning behind them, gets them fixed, and often surfaces context that changes a rating.
7. Retest the fixes
The audit is not finished when the report is sent; it is finished when the serious findings are confirmed fixed. A retest of the high and critical items, a few weeks later, should be part of the price.
What the audit report should contain
Ask any provider for a sample report before you sign. A useful one has five parts:
- A one-page summary for the person who paid: the answer to the questions from step 1, the count of findings by severity, and the three things to do first.
- Scope and method: what was read, what was not, which commit, which tools, and how much time was spent. Without this you cannot tell a thorough audit from a quick one.
- Findings, ordered by severity, each in the format above.
- A remediation plan: findings grouped into "this week", "this quarter" and "when you next touch that code".
- What is good. Strengths matter, because they tell you what not to rewrite.
Severity should follow a published scale so it means the same thing to everyone. For vulnerabilities, CVSS is the common reference; for maintainability, a plain scale is enough:
| Severity | Meaning | When to fix |
|---|---|---|
| Critical | Exploitable now, with serious impact (data exposure, account takeover, money) | Before anything else ships |
| High | Serious, but needs a condition or an insider to exploit; or a defect that will cause an outage | This sprint |
| Medium | Real weakness with limited impact, or a maintainability problem slowing every change | This quarter |
| Low | Hygiene and consistency | When the code is next changed |
When should you commission a code audit?
Commission one when a decision is about to rest on code you have not read yourself. The common moments:
- Before launch or before a sales push, when the first serious customer will ask security questions.
- Before a penetration test. An audit finds the logic flaws a pen test might miss and makes the pen test cheaper, because the obvious findings are already fixed.
- When you inherit a codebase, from an agency, a freelancer, a departing team or an acquisition, and need to know what you now own.
- Before a modernisation programme, because choosing whether to rehost, refactor, rebuild or replace a legacy system starts with knowing what the code actually does.
- Before raising money or selling, so the buyer's due diligence finds nothing you did not already know.
- After a large amount of AI-generated code has landed. Generation got cheap; verification did not.
- After an incident, to find the other places the same mistake was made.
An audit answers one question at one moment. If a new technical question lands every week and nobody inside the company owns the answers, the fix is not another audit but a part-time owner: what a virtual CTO covers, and when you need one.
What it costs to skip one
Skipping an audit does not save the cost of the findings. It moves them to a worse moment. A missing ownership check found in an audit is a one-line fix and a new test. The same check found by a customer is a disclosure, a conversation with lawyers, and a week of the team's time rebuilding trust. A maintainability problem found before a handover is a line in the contract; found after, it is the new team's first quarter.
What a code audit costs depends mainly on four things, so expect a quote to ask about them: the size and number of repositories, how many languages and platforms are involved, how deep the security reading must go, and whether a retest and a walkthrough are included. A quote given without asking about any of these is a scanner run.
How to choose between code audit services
The checklist I would use if I were buying:
- Who reads the code? A named senior engineer whose background matches your stack, not "our team".
- Manual reading, stated in hours. The proposal should say how much time goes into reading by hand, not just which tools run.
- A sample report, redacted, in the format you will receive.
- Fixed scope and fixed price, with the retest included.
- Access handled properly: NDA first, read-only access, no production data, access removed at the end.
- Independence. If the provider also offers to fix what it finds, that is fine and often efficient, but the report should stand on its own, so you could hand it to anyone.
- No certificate promises. An audit can show your code meets a standard's technical controls; it does not make you compliant with SOC 2, ISO 27001 or HIPAA by itself.
What a code audit will not tell you
An audit reads the code as it is at one commit. It will not find a vulnerability that lives only in production configuration it was not shown, it will not tell you whether the product will sell, and it will not keep the code healthy afterwards. That last part is the team's job: the pipeline checks, the reviews and the habits. A good report ends by recommending which of those to put in place so the next audit has less to say.
FAQ
How long does a source code audit take?
It depends on the size of the codebase and the depth agreed in the scope. A single product with one backend and one front end is usually days of work rather than weeks; a platform with several services and mobile apps takes longer. The automated pass is quick; the manual reading of the critical paths sets the timeline.
Is a code audit the same as a penetration test?
No. A penetration test attacks the running system from outside; a code audit reads the source from inside. Audits find logic flaws, such as missing ownership checks, that testers can miss. Pen tests find deployment and configuration problems an audit cannot see. Many teams do the audit first, fix the findings, then test.
Do I need to share production data or credentials?
No. A source code audit needs read-only access to the repositories, the CI configuration and a description of how production is deployed. If an auditor asks for production credentials or customer data for a code audit, ask why. Sign an NDA first and revoke access when the engagement ends.
Can automated tools replace a manual code audit?
They cannot. Scanners are good at known patterns: leaked secrets, vulnerable dependencies, unsafe functions. They do not understand that one customer must never see another customer's data, or that a refund can be issued twice. Those business-logic flaws are where the serious findings usually are, and they need a person.
What should I do with the report?
Fix the critical and high findings first, add a test for each so it cannot return, and schedule the retest. Put the medium findings into the next quarter's plan. Then adopt the pipeline checks the report recommends, so the same classes of problem are caught on every pull request from now on.
If you want a second reader
Reading other people's code, and making apps ready for a penetration test, is part of the contract work on my hire page. I agree a fixed scope and the questions up front, read the critical paths by hand, and stay for the walkthrough and the retest.