Secure code review vs penetration testing

Secure code review reads the source for flaws, while penetration testing attacks the running application. This page shows when each fits, what each misses, and when a combined engagement is worth buying.

On this page

Secure code review vs penetration testing: which one to buy first

Buy secure code review first when the risk sits in how the application decides things, and buy penetration testing first when the risk sits in what an outsider can reach. Code review reads the source for flaws in business logic, access control, cryptography and custom authentication, which is where a shortlisted application is most likely to fail before release. Penetration testing attacks the running application the way an external attacker would, so it validates exposed behavior, configuration and production-like controls. If your application uses a home-grown login scheme or complex authorization rules and has not yet shipped, source-led review is usually the better first spend. If the code has been stable and the question is whether an auditor or customer can break in from outside, a penetration test answers that more directly.

The OWASP Web Security Testing Guide v4.2 notes that source code review is complete and accurate for competent reviewers but needs highly skilled people and can miss issues in compiled libraries and runtime errors. Penetration testing reaches the code actually exposed but comes late in the life cycle and only tests from the front. Before you sign a statement of work, ask the vendor whether the test will use documentation and source, which OWASP ASVS 5.0.0 recommends as a hybrid approach, and confirm which reviewer skills and which environment the work will cover.

In practice the two are often combined. The WSTG recommends a mix of techniques that puts more weight on the early development phases, and NIST SP 800-115 notes that organizations often combine techniques to reach an in-depth assessment at an acceptable level of risk. A practical sequence is a source-led review before release, followed by a penetration test of the deployed build that checks whether the reviewed logic holds in production configuration. Ask each provider to state in writing which findings came from source, which from the running system, and how the two lists were reconciled.

Which approach fits your situation

When your team writes the code and the application is still changing, source-led review gives you the most leverage. OWASP WSTG v4.2 notes that penetration testing comes too late in the development life cycle to be the main control here, and it recommends weighting the early phases more heavily. Pair targeted manual review of high-risk code (authentication, authorization, session handling, cryptography and payment logic) with automated static analysis on each commit. Penetration testing still has a role before release, but it should confirm what the review found, not discover the design flaws for the first time.

  • Start with the code that carries trust decisions: Review login, token issuance, access checks and cryptographic use first, since these are where a reviewer adds the most.
  • Use automated analysis for breadth: Static tools cover known patterns on every commit, which leaves reviewer time for logic that tools cannot judge.
  • Schedule a tester after the review: A penetration test against a staging build confirms exposed behavior and catches gaps between the code and the deployed configuration.
  • Watch for change rate: If the codebase changes weekly, plan review as a recurring activity rather than a single engagement.
  • Plan for reviewer skill: WSTG notes that source review needs highly skilled reviewers, so confirm the reviewer's experience with your language and framework before you buy.

Check whether your build pipeline produces the same artifact that reaches production, because a review of code that differs from what is deployed answers the wrong question.

How the two approaches compare on goals, scope and method

This table compares secure code review and penetration testing factor by factor, from goal and input to risk and repeatability. Read it to see which approach answers which question, then use the rows on timing and skill to decide where each belongs in your program. The main takeaway is that the two methods read different evidence, so they find different flaws.

FactorSecure code reviewPenetration testing
Primary goalFind flaws in how the code is written, including design and logic errors that are visible in the sourceFind weaknesses that an attacker could exploit in the system as it is deployed and exposed
Input to the testerSource code, and where available design documentation and build configurationThe running application, its interfaces and, in graybox work, credentials or documentation supplied by the client
Testing viewpointInside the code, reasoning from the implementation outwardFrom the attacker's position, usually working from the front of the application
ActivityReading and reasoning about code paths, data flows and trust decisionsSending requests, probing inputs and attempting exploitation to confirm impact
Risk to systems (NIST SP 800-115)Review techniques are passive and pose minimal risk to systemsPenetration testing uses real exploits against production systems and data and carries high risk
Timing in the life cycleUsable before the code is deployed, and well suited to earlier development phasesUsable once a running build exists, which in the WSTG view comes too late to shape early design choices
Tester skill profileNeeds highly skilled reviewers who understand the language, framework and secure coding patternsNeeds skilled testers who can chain behavior, adapt to the target and report exploitable impact
RepeatabilityRepeats well when rerun on the same code or changes, and can be narrowed to the modules that changedVaries more with each tester and scope, so results depend on the methodology and the time allotted
What to confirm with a providerWhether the review covers compiled libraries, runtime behavior and deployed configuration, which the WSTG lists as blind spotsWhether the test is graybox or blackbox, what documentation is supplied, and whether the scope includes the backend and APIs

What code review finds that penetration testing misses, and the reverse

Source code review and penetration testing look at the same application from opposite ends. The cards below set out what each method sees, what it cannot see, and the points where a combined engagement closes the gap.

Code review finds design flaws in custom logic

A competent reviewer reading the source can spot a home-made authentication scheme and see that it has no secret key. OWASP WSTG v4.2 uses an example of a single sign-on scheme that MD5-hashes the username and date, where a manual review would likely expose the weakness quickly. A black-box scanner sees only an unpredictable-looking hash and has no way to judge how it was built. Check whether your reviewers can read the authentication, session and cryptography code paths, not only the framework calls.

Code review is only as good as its reviewer

OWASP WSTG v4.2 lists completeness and accuracy as strengths of source code review when the reviewer is competent, and speed as well. It also lists the need for highly skilled reviewers as a drawback. Ask who will perform the review, what security and language experience they bring, and how they will record coverage so the result can be checked later. A review by a generalist may look complete and still miss the flaws that matter most.

Code review cannot see compiled or runtime behavior

Source review does not reach into compiled libraries, and it often misses errors that appear only at runtime, such as failures under load or unexpected states after a dependency returns an error. WSTG v4.2 names both as blind spots. If your application relies on vendor binaries, closed-source components or complex configuration, plan a dynamic test or a binary analysis alongside the review. Confirm which of these parts the review scope covers in writing.

Code review may not match what runs in production

The code a reviewer reads may differ from what is deployed, because of unmerged branches, build-time changes, feature flags or container images built from a different commit. WSTG v4.2 lists this as a drawback. Before the review starts, confirm the commit or build identifier under review and compare it with the artifact in production. Penetration testing does not have this gap because it tests the running system.

Penetration testing tests what is actually exposed

A penetration test works against the deployed application, its real configuration, network path and reverse proxy, so it reports what an attacker could reach today. WSTG v4.2 notes that it tests the code actually exposed and can be fast to run. This makes it the stronger check on deployment errors such as a debug endpoint left open or a missing header on the production load balancer. Ask the tester to confirm which environment is in scope and whether it matches production.

Penetration testing comes late and sees only the front

WSTG v4.2 says penetration testing comes too late in the development life cycle, and that it tests only from the front. Flaws found at this stage are usually more expensive to fix, and an attacker who already has credentials or sits inside the network can see paths the tester never tried. Schedule a penetration test after a source review rather than as the only check, and state in the statement of work which roles and starting positions the tester will use.

When compliance frameworks call for source review, penetration testing or both

Start by reading the control text your framework actually names, because the two test types are not interchangeable in the eyes of assessors. NIST SP 800-53 Rev. 5 control SA-11, Developer Testing and Evaluation, lists manual code reviews alongside penetration testing, static code analysis and dynamic analysis as enhancements. Its guidance says custom software may need manual code review, a security architecture review and penetration testing, as well as static, dynamic, binary or hybrid analysis. For a federal or federally aligned system that builds its own application, a penetration test on its own is unlikely to close the SA-11 question. Ask your assessor which enhancements apply to your system and which baseline selects them, since the catalog and the baseline document are separate sources.

Penetration testing has its own control family entry. NIST SP 800-53 Rev. 5 control CA-8, Penetration Testing, covers the testing itself, and its enhancement CA-8(1), the independent penetration testing agent or team, is selected only in the high baseline according to SP 800-53B Release 5.2.0. If your system sits in a moderate baseline, confirm whether CA-8 alone is in scope and whether your organization wants independence anyway. In payment environments, the PCI SSC Penetration Testing Guidance (v1.1, September 2017) states that running an automated tool does not satisfy the penetration testing requirement. Plan for a manual tester-led exercise and ask the assessor to confirm how they will evidence it.

For EU financial entities, DORA Article 25(1) lists source code reviews, where feasible, alongside penetration testing and open source analyses. The words "where feasible" leave room for judgment, so document the reason if you do not review source for a given system, and agree that reasoning with your competent authority or assessor before the test cycle. Build a short matrix that maps each framework requirement to the test type that satisfies it, the evidence it produces and the owner who signs it off. Confirm exact obligations against the framework text and with your assessor, since this page does not give legal or audit conclusions.

How a combined engagement is sequenced across the life cycle

A combined engagement puts source-led review where flaws are cheapest to fix and keeps penetration testing for the built system, so each method covers the blind spots of the other. The sequence below is illustrative and should be adjusted to the application, its risk and the team's release process.

  1. Start with threat modeling and documentation review

    Before code is written or changed, the team and the assessor review architecture diagrams, data flows, trust boundaries, authentication design and any existing threat model. The assessor, often working alongside the architects, identifies the high-risk modules and the security decisions that most need checking, such as custom session handling or access control logic. The step closes when the high-risk modules are listed, each with a named owner and the design documents that a reviewer will use. Illustrative only: a small internal tool may need a short document pass, while a payments service needs a fuller one.

  2. Run source-led review of high-risk modules

    During development, a security reviewer reads the source code of the modules flagged in the previous step, alongside the design documents and any automated static analysis results. The reviewer looks for logic flaws, authorization gaps and misuse of cryptography, which automated tools often miss. Findings are logged against the code and the design, and developers fix them in the normal workflow. The step closes when each flagged module has a review record, every finding has a status, and any design change has been fed back into the threat model.

  3. Prioritize review before the build is frozen

    The WSTG advises weighting early development phases more heavily, so this is the point where the team decides how much of the remaining budget goes to late testing. The security lead compares review findings with the list of modules still changing and moves reviews forward for code that is not yet stable. Reviewing code that will change again wastes effort. The step closes with a written decision on which modules are reviewed in their final form and which will be covered only by penetration testing.

  4. Penetration test the built system before release

    Once a release candidate is built and deployed to a staging environment that matches production, a tester attacks the running application using the documentation and source references from earlier steps. Because the tester knows the design, the work focuses on exploitable paths and on checking whether reviewed controls behave as the code suggests. The source gives the tester a way to confirm that code deployed is the code reviewed, which the WSTG notes is a risk for black-box testing alone. The step closes with a report of exploited findings, each tied to a code location or design decision.

  5. Fix and retest the confirmed findings

    Developers fix the confirmed findings, and the tester retests each one against the same scenario that produced it. The retest checks that the fix addresses the root cause, not only the symptom, and that the change did not reopen another path. Findings closed in review are verified against the code change as well. The step closes when every finding has a retest result of fixed, accepted with a documented risk decision, or still open with an owner and date.

  6. Validate detections against the tested techniques

    The security operations team checks whether the monitoring stack would have detected the techniques the testers used, such as credential abuse, injection attempts or unusual access patterns. CIS Safeguard 18.4 asks for security measures to be validated after each test so that detections cover those techniques. Gaps become detection engineering tasks with owners. The step closes when each tested technique is marked as detected, partially detected or not detected, and each gap has a tracked action.

  7. Record evidence and schedule the next cycle

    The team collects review records, test reports, retest results and detection validation into one evidence package, mapped to the controls the organization needs to show. The package also records what the team would change next time, such as modules that were reviewed too late or scenarios the tester could not reach. The step closes with an agreed date for the next review and test cycle and a note on scope changes. Ask any assessor to confirm in writing which evidence they will produce, since DeployOpen prepares evidence but does not issue audit reports.

What you receive from each engagement

This table compares what a secure code review and a penetration test typically hand back, from finding format to retest evidence. Read it to decide which artifacts your engineers, auditors and risk owners will need, then ask each provider to put those artifacts into the written scope before work starts.

DeliverableSecure code reviewPenetration test
Finding locationAnnotated findings tied to file, function and line number, with the data flow that reaches the flawAffected URL, endpoint, parameter or host, with request and response evidence from the running system
Proof of impactReviewer reasoning and the code path showing how the flaw could be reached, often without a live exploitExploit narrative with captured evidence, showing what an attacker could access in the tested environment
Attack pathsData-flow and trust-boundary observations across modules, which may or may not be exploitable in deploymentChained attack paths from initial access to impact, showing how separate weaknesses combine
Remediation guidanceCode-level fix direction, secure pattern references and notes on where the same pattern recursFix direction at the configuration, component or code level, usually tied to the observed behavior
Coverage statementWhich modules, commits or components were read, and which were excluded or could not be builtWhich hosts, roles, test accounts and functions were exercised, and which were out of scope
Retest resultsRe-review of changed code against each original finding, recorded by commit or versionRetest of each finding against the deployed build, recorded with new evidence
Ask each provider to specifyRepository and commit range, languages, build access, whether dependencies are reviewed, and the written report formatTargets, test roles, environment (production or staging), rules of engagement, and the evidence format for each finding

What drives the cost and duration of each approach

Both secure code review and penetration testing are priced from written scope, so the same few inputs move the effort up or down for each. The cards below cover the inputs that most often change a quote, and what to request from a provider before you compare numbers.

Code size and language mix

A reviewer's time follows the volume of code in scope, how many languages it spans, and how much of it is security-relevant, such as authentication, session handling, cryptography and authorization logic. Ask the provider to state which modules are in scope, the approximate size of each, and whether generated code, test code and vendored libraries are excluded. For a penetration test, ask how the same application surface maps to test cases instead of lines of code.

Third-party components in scope

Whether the reviewer reads third-party or compiled dependencies changes the scope materially. OWASP WSTG notes that source code review can miss issues in compiled libraries, so a quote should say whether dependencies are reviewed from source, tested only through their behavior, or left to a separate software composition analysis. Ask which components are covered and how the provider handles components it cannot read.

Source, documentation and environment access

Source-led and documentation-led work is only as fast as the access the client provides. Confirm repository access, branch and commit scope, architecture diagrams, data flow documents and a working test environment before the engagement starts. Missing material usually shows up as extra days of discovery, which is why a quote should list each artifact and who supplies it.

Reviewer and tester skill level

OWASP WSTG lists the need for highly skilled reviewers as a drawback of source code review, and the same is true of manual penetration testing. Experienced staff move faster and find more logic and access control flaws, but they cost more per day. Ask who will perform the work, their certifications and framework experience, and whether senior staff review the findings.

Attack surface and test data setup

A penetration test is driven by how many entry points, roles, integrations and user journeys the application exposes. A deployed environment with realistic test accounts and seeded data reduces setup time, while missing accounts or unstable staging environments add it. Ask how many roles and external integrations are in scope, who provisions test accounts, and whether testing runs in staging or a production-like copy.

Retests and one-time versus recurring work

A first review or test is only part of the total cost. Fixes usually need a retest, and a program that runs on a schedule or after each major release recurs. Ask how many retest rounds are included in the fixed scope, what happens to additional rounds, and whether the quote covers a single engagement or an agreed retainer for continuing assurance.

Questions buyers ask before choosing code review or penetration testing

Can a secure code review replace a penetration test?

No. The OWASP Web Security Testing Guide v4.2 says no single technique is enough and recommends a mix, and NIST SP 800-115 notes that organizations often combine techniques to reach an in-depth assessment at an acceptable level of risk. Code review finds flaws that are hard to see from outside, such as a home-made single sign-on scheme that hashes the username and date with no secret key. Penetration testing checks what is actually exposed in the deployed system, including configuration, infrastructure and runtime behavior that the source may not reveal. Where a buyer needs both kinds of evidence, a combined engagement is the usual answer.

What does a code review or penetration test cost, and what drives the quote?

No supplied figure gives a price for either activity, so treat any number you see elsewhere with caution and ask for a written quote. DeployOpen does not publish a price list. Most engagements are fixed-scope, and the quote follows from the agreed scope, deliverables and timeline. The main cost drivers are the size and number of codebases or applications, the number of user roles and workflows to test, whether source and documentation are provided, the depth of the work (for example, the ASVS level targeted), and whether retesting is included. Ask for the cost of each phase separately so you can compare a review with a test on the same scope.

How long does each activity take, and what does it need from my team?

Duration depends on the written scope, so ask for a timeline tied to specific deliverables rather than a generic estimate. Both activities need named contacts who can answer questions quickly and approve testing windows. A code review needs read access to the relevant repositories, build configuration and design documents. A penetration test needs test accounts for each role, a staging or production-like environment agreed in advance, and rules of engagement that NIST SP 800-115 describes with a template in Appendix B. Confirm early whether testing may touch production data and who can stop a test if something breaks.

Can our own staff run a code review or penetration test?

Internal staff can run parts of both, but the skills differ. OWASP WSTG v4.2 notes that source code review needs highly skilled reviewers, and PCI SSC's Penetration Testing Guidance v1.1 describes penetration testing as essentially a manual process, so running an automated tool does not meet a penetration testing requirement on its own. Internal teams often do well with routine scanning, threat modeling and a first pass on code, then bring in an external tester for an independent view. Ask whether your team has people who can reason about access control, business logic and cryptography misuse before deciding what to keep in-house.

What changes when the source code is not available?

Without source, the work becomes a black-box penetration test, and you lose the code review advantages the OWASP WSTG lists, such as completeness and accuracy for competent reviewers. OWASP ASVS 5.0.0 strongly encourages documentation or source code led (hybrid) testing over testing without either. If source is unavailable, ask the tester to use architecture diagrams, API specifications and configuration files, and expect findings to be harder to trace to root cause. Some issues, such as a flawed scheme that looks random from outside, may stay hidden. Record this gap in the statement of work so the report is read correctly.

How often should we repeat each one?

Frequency should follow your risk, your release pace and any rule that applies to you. CIS Controls v8.1 Safeguards 18.2 and 18.5 ask for external and internal penetration tests at least annually, and Safeguard 18.4 asks for security measures to be validated after each test. NIST SP 800-115 suggests regularly scheduled scanning interspersed with periodic penetration testing. Code review is usually tied to significant changes and to the development life cycle rather than a calendar, so repeat it when a new component, authentication flow or data path is added. DORA Article 26 sets a three-year interval for threat-led testing for entities so identified by their competent authority.

What should our statement of work say for code review and penetration testing?

Name the objective, the applications and versions in scope, and the exact boundaries, including hosts, APIs, roles and environments. State whether the work is code review, penetration testing or both, and cite the methodology used, such as NIST SP 800-115 or the OWASP WSTG v4.2. Specify what access the tester receives, the rules of engagement, data handling and escalation contacts, and the deliverables with their format. Also define retesting, how severity will be assigned, and who signs off on closure. Ask the provider to confirm which skills and certifications their testers hold, and avoid wording that promises a certification or compliance outcome.

How DeployOpen scopes a combined engagement

A combined engagement starts with a written scope that says which parts of the source code, which build artifacts and which running environments each activity covers. DeployOpen plans and delivers security testing inside the client's own infrastructure, including their cloud accounts, data centers or air-gapped networks, so the first scoping decision is where the code repository, the CI pipeline and the staging and production targets sit, and who on the client side grants read access to the repository and test credentials for each role. Most engagements are fixed-scope, so scope, deliverables and timelines are agreed in writing before any work begins. Ask for a statement of work that names each source-led task (for example, a review of authentication and session handling in a specific module) alongside each exploit-led task against a named application, environment and set of user roles, so the two halves can be checked against each other later.

Two boundaries matter most for the reader to settle before signing. First, DeployOpen does not issue audit reports, attestations or certifications. If a regulator, customer or assessor needs evidence for an assessment, DeployOpen prepares systems, controls and test records, and the independent auditor or certification body makes the determination. Second, combined work can be delivered as a one-off fixed-scope engagement or supported by a retainer for continuous testing, and the choice depends on how often the code changes and whether the findings need retesting after each release. Ask for the retest terms, the handling of out-of-scope findings and how the code version under review is pinned to the version later tested, since a review of one commit and a test of another will not reconcile.

How DeployOpen delivers secure code review and penetration testing

DeployOpen plans and runs secure code review and penetration testing as part of security testing for self-hosted platforms inside the client's own infrastructure. Engagements are fixed-scope, so the source access, target systems, test windows and deliverables are agreed in writing before any testing starts.

How we scope

  • Confirm which repositories, branches and build versions are in the review, and which deployed targets are in the penetration test.
  • Record whether the tester receives source, design documents and credentials, since that choice changes what the work can find.
  • Agree rules of engagement covering test windows, production versus staging use and escalation contacts before any traffic is sent.

How we test

  • Review selected source code manually for access control, business logic and cryptographic misuse, and pair the review with the deployed application.
  • Run penetration testing against the exposed application, using the source and design documents where the agreed scope provides them.
  • Record which findings came from the code, which came from the running system, and which needed both to confirm.

How we hand over

  • Deliver written findings with reproduction steps, affected code locations or endpoints, and a fix recommendation for each issue.
  • Map findings to the control requirements your assessors use, such as ASVS requirements or SA-11 enhancements, where the agreed scope asks for it.
  • Walk your engineering and security teams through results and agree retest criteria, so fixes can be verified against the original findings.

How we support

  • Retest agreed findings after fixes are merged, within the scope and timing set out in the written agreement.
  • Offer ongoing support, periodic re-testing and continuous testing as retainers when your release cadence needs them.
  • Confirm with us before the engagement which deliverables, retest rights and retainer terms are included in your quote.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.