Est.

Code Audit Basics Before Acquiring or Inheriting a Codebase

Find hidden risks in code you're about to own with an independent audit.

Columnist · · 11 min read
Cover illustration for “Code Audit Basics Before Acquiring or Inheriting a Codebase”
Vetting and Due Diligence · September 29, 2026 · 11 min read · 2,576 words

A code audit ends with a written report, findings ranked by severity, reproductions attached so the next engineer can confirm the bug, and a prioritized plan for fixing what's broken. That's the whole product. Not a rewrite, not a cleanup, just an honest photograph of the code as it exists at one frozen commit, graded and priced.

That distinction matters because the term gets confused with two neighbors constantly. A code review is what a team does to itself, continuously, one pull request at a time. It's internal and fast, and genuinely useful, but it's also the opposite of independent. A penetration test doesn't read a single line of source. It attacks the running system from outside and reports what broke. Useful, but blind to anything that hasn't been exploited yet. An audit sits between them: it reads the code itself, independently, and produces a document a stranger could trust. The three aren't competing products. They stack. Buying the wrong one, thinking a pen test covers what an audit covers, wastes money.

So why does inheriting a codebase specifically demand this? Because someone is about to make an expensive, hard-to-reverse decision on code they don't fully understand, and an audit replaces a gut feeling with evidence. Four moments trigger this most reliably: before an acquisition, before a funding round riding on inherited code, when the bug rate on a handed-off project starts climbing, and at the actual team hand-off itself. Every one of those involves taking ownership of work somebody else wrote, under time pressure, with money on the line.

What's actually at stake? The CISQ 2022 report put the annual US cost of poor software quality in the trillions, with the largest single share in accumulated technical debt, and an audit is how you find out how much of that bill is hiding in the repo you're about to sign for.

How to read a codebase you've never seen before: the pre-audit setup that determines what you'll find

A useful audit doesn't start by running a scanner. It starts with a plan, because without defined scope, an audit either misses the parts that matter or burns hours combing through code that carries no real risk.

The first move is mechanical: freeze the codebase. Tag a release, or pin a staging branch, so every finding traces back to one fixed commit. Findings need to be reproducible against a known state, not a moving target that's changed by the time the report lands. From there, scope gets defined before a single tool runs. Is this a full-codebase review, or a targeted pass on the modules that actually carry risk, authentication, payment processing, anywhere sensitive data moves? Is the goal security, code quality, compliance, or all three at once? Is the focus on new code, the legacy layer beneath it, or both? And what triggered the audit in the first place, an acquisition, a hand-off, a scaling push? Each answer changes where the auditor spends time.

Access needs structure too. Sensitive repositories get protected, the list of people who can see the source during review gets limited, and the chain of custody on the findings report gets documented. That last part sounds bureaucratic until the report becomes evidence in a negotiation.

Before any tool opens a file, gather what already exists: architecture documentation, infrastructure details, dependency manifests, prior security reports. If none of that exists, that absence is itself a finding, and often an important one. From day one, certain areas deserve priority regardless of the scope document: API endpoints, authentication and session flows, anything that handles data, any module that touches sensitive user information.

One decision shapes everything downstream: who does the audit? Internal reviewers catch problems early and know the system's history, but familiarity breeds blind spots, the deeper structural issues tend to go unseen precisely because the reviewer built half of them. External auditors bring no such bias, and they're often required outright for compliance frameworks like SOC 2 or ISO 27001. More to the point, an external audit produces the kind of report a board or a buyer will actually trust. For an acquisition or a hand-off, external is close to the only sensible call. Independence is the entire value proposition.

The nine dimensions a complete audit must cover

A complete audit runs across nine dimensions of risk and debt. Skip one, and the resulting clean bill of health is false because the picture was incomplete.

Five of these come from the formal structure most audit firms use, built out of more than fifteen years of audits spanning healthcare, fintech, and logistics software. Frontend review covers page load times, mobile compatibility, whether the code follows current standards for the framework in use, and accessibility. Backend review looks at API endpoints, database query efficiency, how much traffic the system can actually take, and whether the architecture has room to grow. Infrastructure and DevOps review checks server configuration, deployment pipelines, cloud resource usage, how much of the CI/CD pipeline runs automated tests, and how current the dependencies are. Security and compliance review maps the code against OWASP's vulnerability categories and checks alignment with whatever regulation applies, HIPAA, GDPR, PCI-DSS. Documentation and maintainability review looks at comments, API documentation, naming conventions, and flags libraries that have quietly gone stale.

Architectural decay is structural: decisions made years ago that have calcified into constraints nobody can undo cheaply. It's the hardest of the nine to quantify and the most expensive to ignore. Consistency rot appears in patterns that diverge across the codebase, indicating that multiple people, or multiple eras, touched the code without a shared style guide holding it together. Type and contract debt covers missing or wrong data types, function contracts nobody wrote down, assumptions between modules that live only in someone's head. And error handling and observability asks a blunt question: does the system tell anyone when it breaks, or does the customer find out first?

One firm, Code Climate, turns this into a number: a technical debt ratio, total time spent on debt divided by total time spent building, expressed as a percentage and mapped onto a letter grade from A to F. It functions as an early warning system, catching drift before it becomes a crisis.

None of this happens by hand from scratch. Automated tools take the first pass. SonarQube, Semgrep, CodeQL, and Snyk flag mechanical issues at scale, and gitleaks scans git history for hardcoded secrets such as passwords, API keys, and tokens. These open-source tools are approachable enough for a team to run themselves. What they can't replace is the senior architectural read, the judgment call on whether a pattern is a smell or a genuine risk, and the report written in language a board will actually trust. That part still needs a person. The additional dimensions from the nine-category debt framework round out the full set of nine dimensions a complete audit must cover.

The security layer: OWASP Top 10:2025 requirements in inherited code

Security scoring needs a moving target of its own. OWASP's Top 10 was announced in its 2025 form in November of that year, with the final version released in January 2026, and most audit guides in the market still haven't caught up to it, scoring code against the older 2021 list instead. A report that grades a codebase against outdated categories is grading it against the wrong test.

Certain failures recur in inherited code, particularly anything built fast by an agency or a small founding team. Missing authentication is the top finding, API endpoints with no auth check at all, one of the single most common findings in prototype-stage work. Right behind it is no input validation, a gap that lets SQL injection and cross-site scripting through, which static analysis tools catch fast once someone points them at the code. Hardcoded credentials and API keys, sitting in the source or buried in version history, appear constantly too, and gitleaks and TruffleHog exist specifically to find them.

Compliance runs on a separate track from vulnerability scanning, and it needs to get built into scope at the start, not bolted onto the report at the end. GDPR concerns how data gets handled, how consent gets recorded, whether the right to erasure is implemented or just claimed in a privacy policy. HIPAA asks about encryption, access control, and audit logging, especially relevant for anything touching healthcare or human services. PCI-DSS governs how payment data moves and where it's stored.

Supply-chain documentation has its own new baseline. An audit checking SBOM completeness against the old 2021 baseline is checking against a standard that no longer applies.

AI tools have changed the pace of scanning, faster pattern detection, wider coverage across a large codebase in less time. But the pattern across every source on this is consistent: human oversight stays essential, because these tools throw false positives and have no way to judge business logic or context. A pen test rounds the picture out from the other direction: the audit reads the source and finds the structural flaw, the pen test attacks the running system and proves the flaw is actually exploitable. Before a funding round or a major acquisition closes, both belong in the process together.

Dependency and supply-chain risk: the part of the codebase most teams can't see and most audits underweight

Every codebase carries two layers of dependencies. The direct ones are visible and deliberate, chosen and imported on purpose. The transitive ones, the dependencies of those dependencies, are inherited without anyone choosing them, and the total surface area they create typically runs far larger than most teams ever recognize.

A shallow dependency sitting behind one clean abstraction boundary can get swapped out in a day if it turns out to be a problem. A deep one, whose patterns have spread into how every feature gets built, has effectively shaped the whole product. Replacing it isn't a swap anymore; it's a partial rewrite. A serious audit maps not just what's present in the dependency tree but how far its roots actually reach.

License conflicts turn out to be one of the sharper deal-killers in this space. Research from audit-checklist studies found that 68% of audited codebases carry license conflicts, up from 56% in the prior measurement period, the single largest year-over-year jump on record, and one audited codebase alone held 2,675 distinct conflicts you-source.com. That's not a rounding error. That's a legal review waiting to happen after the deal closes.

Third-party code, more broadly, is now the dominant source of long-term security debt. It doesn't just carry risk. It carries risk that lingers.

The incidents aren't hypothetical. Early in 2025, a vulnerability tracked as CVE-2025-30066 hit tj-actions/changed-files, a GitHub Action used widely across CI/CD pipelines, exposing API tokens and private keys across more than 23,000 repositories after attackers injected code that dumped those secrets straight into workflow logs. Supply chain attacks overall have surged more than 300% since 2024 by industry estimates ainformat.com.

The response to all this has shifted from periodic checks to something continuous. Software Composition Analysis now runs embedded in every deploy rather than as an occasional CI gate, automatically identifying every open-source component in a build and checking it against vulnerability databases, license rules, and known malicious package feeds. Without a full bill of materials behind that process, neither a buyer nor an inheriting team has any real way to know what they've actually taken on. The State of Software Security Report from Veracode and the Cyentia Institute found that 66% of the most dangerous, long-lived security debt originates from third-party code, with a remediation half-life for third-party flaws of 358 days against a shorter average of 243 days across all scan types State of Software Security Report / Veracode you-source.com. Malicious Axios versions 1.14.1 and 0.30.4 were published after attackers used a compromised maintainer account, adding a malicious dependency that delivered a cross-platform remote access trojan for Windows, macOS, and Linux, with Microsoft attributing the campaign's infrastructure to Sapphire Sleet, a North Korean state actor.

Diagram: Third-Party Code Carries the Longest Debt. Visualizes: Show the contrast between two remediation timelines for security debt: third-party flaws take 358 days on average to remediate, versus 243 days across all scan types — a 47% longer…

The AI-generated and agency-built MVP: why the codebase you're inheriting is often a prototype wearing a production costume

Tools like Lovable, Cursor, and Claude Code let a founder go from idea to working prototype in hours now, and that's a genuine edge for getting to market fast. But speed like that creates its own predictable category of debt, one that audits run into constantly at this point.

These tools optimize for speed of generation over security, which is the core issue. Missing authentication on API endpoints tops the list again. Missing input validation follows right behind it, with SQL injection and cross-site scripting vulnerabilities present out of the box in generated code. Row-level security at the database layer is often absent, so one user's query can, in principle, surface another user's records.

There's a maintainability signal sitting alongside the security one. GitClear's report found an eightfold increase in duplicated code blocks across the codebases it studied, a pattern that correlates directly with AI-assisted generation at scale. Duplication like that isn't a style complaint.

Platform lock-in deserves its own line in the report too, and it's the finding most people miss until it's too late. If the product's hosting sits inside Lovable's infrastructure, or its database lives inside Replit's setup, migrating off that platform later could mean a rebuild, not a migration. That's a dependency risk, not a matter of taste, and it needs to be written up as one.

So what does actual production-readiness require, versus what an MVP has? A real separation between testing and live environments. Automated release pipelines, so a small change doesn't take the whole system down. Error monitoring that catches a failure before a customer does. Authentication and authorization built correctly rather than approximated. A database schema designed with growth in mind, not just today's data volume.

The audit's real job here is to draw a line: this part needs remediation, this part needs replacing. In roughly 80% of cases, cleanup turns out cheaper and faster than a full rebuild, but the audit is what tells you which category applies. Guessing, without one, is the expensive mistake. Technical debt at this stage is a predictable stage a fast-built product passes through, and an audit gives both sides of a deal a shared, evidence-based language for pricing what it'll take to fix. A security audit of a typical AI-generated project reveals an average of 15–25 critical findings.

How technical debt compounds after acquisition: the financial and operational case for auditing before you sign

Debt that goes unmeasured before a deal closes doesn't stay flat. It compounds, the same way financial debt does, because every new feature built on top of a shaky module inherits that module's weaknesses along with it. A missing authentication check found in month one costs an afternoon to fix.

That's the real argument for auditing before signing rather than after. Once ownership transfers, the negotiating leverage is gone; whatever the report finds afterward is now entirely the buyer's problem to fund, on the buyer's timeline, at whatever rate the market for that remediation happens to be charging that quarter. Before the signature, the same findings serve as a bargaining chip, producing a lower price, an escrow holdback, or a remediation clause written into the deal itself.

An audit conducted early doesn't just protect against the obvious risks either, the security hole, the license conflict, the platform lock-in. That's worth more than a clean bill of health nobody can back up.

Sources

  1. you-source.com
  2. top10.owasp.org

More in Vetting and Due Diligence