BERRY9 IT Services, home +91 86868 92922

Source code review services

A secure code review reads your application's source to find what testing from outside can miss: broken authorization checks, injection sinks, unsafe deserialization, misused cryptography and secrets committed to the repository. BERRY9 pairs manual review with a static analysis baseline and ties each finding to a file, a line and a commit with a code-level fix, working from Hyderabad for teams across India.

Approach
Manual review backed by static analysis
Languages
Java, Node.js, Python, Go, Ruby, C#, PHP
Duration
5 to 10 working days
Starts from
INR 27,000 + 18% GST

Last reviewed

attack path / chained findingsIllustrative
Illustrative attack path: HTTP request → controller → F-01 → F-02 → orders table Findings: F-01, The tenant ID is read from the request body instead of the signed-in session (High); F-02, A sort parameter is concatenated into a raw SQL fragment the ORM passes straight through (High); F-03, A live API key sits in an old commit and was never rotated (Medium). Also mapped: git history, F-03. controller git history HTTP request F-01 F-02 F-03 orders table

PathHTTP request → controller → F-01 → F-02 → orders table

Also mappedgit history · F-03

  1. F-01The tenant ID is read from the request body instead of the signed-in sessionHigh
  2. F-02A sort parameter is concatenated into a raw SQL fragment the ORM passes straight throughHigh
  3. F-03A live API key sits in an old commit and was never rotatedMedium
Illustrative example, not client data: one request followed through the code, from the controller where it arrives to the query that reaches the database, with two findings on the way and a third found in the repository history.

01 / What it is

What a secure code review is, and when you need one

Penetration testing judges an application by its answers. A code review judges it by its reasoning: the checks, queries and calls that produce those answers, including the branches no request happened to exercise.

A secure code review is a security examination of an application's source. A reviewer reads the code with an attacker's questions in mind: where does untrusted input enter, what does the code do with it, which checks stand between a request and the data it asks for, and are those checks written correctly every time. Because the reviewer sees the whole implementation rather than its responses, a review can find flaws on code paths that no test request happened to reach.

Scanners find patterns; people find chains. That is the idea behind how BERRY9 reviews code: a static analysis baseline sweeps the codebase for the cheap, well-known mistakes, and a reviewer spends the engagement on the categories where judgment matters, then explains what to fix in terms of your own code.

Teams tend to ask for a review at one of these moments:

  • Before a large release or a rewrite

    A new authentication flow, a move to a new framework or a module rewritten from scratch is the moment when old protections can quietly disappear. Reading the new code before it ships is cheaper than finding the gap in production.

  • When a test found one flaw and you fear more

    A penetration test proves one endpoint is open to injection or to a missing ownership check. A review answers the next question: where else in the codebase the same idiom repeats, including routes the test never touched.

  • When a scanner's output is too noisy to act on

    Static analysis on its own can produce long lists in which real issues are hard to pick out. A review triages that list, filters the false positives and adds the findings a rule set cannot express.

  • When the code moves money or personal data

    Payment flows, health records and identity data raise the cost of a single mistake in an authorization check or a cryptographic call. These are the categories a manual review is built around.

  • When a customer or auditor asks how code is checked

    Security questionnaires, SOC 2 work and PCI DSS assessments often reach the question of how the software itself is reviewed for security. The compliance section further down sets out what a review can and cannot show.

  • When you inherit a codebase

    Code written by a previous vendor, an acquired team or an open-source project you now maintain comes with assumptions nobody on your team made. A review maps its trust boundaries and tells you which of those assumptions are unsafe.

The codebases we review come from these industries:

  • SaaS
  • Pharma
  • Fintech
  • Education
  • Manufacturing
  • Healthcare

02 / What we review

What a source code security review covers

The review concentrates on the classes of bug where a careful reader beats a rule set. Six areas make up the coverage, and a pattern catalog built from what we find sits on top of them.

  • Authentication and session management

    How passwords are stored and compared, how session identifiers are generated and rotated on sign-in and privilege change, how reset tokens expire, and whether token verification pins the algorithm instead of trusting a header.

  • Authorization and tenant isolation

    Whether every handler that returns or changes an object checks that the caller may touch it, whether role checks sit in one central layer or are scattered by hand, and whether tenant IDs are enforced where the data is queried.

  • Cryptography

    Algorithms, key handling, initialization vectors and sources of randomness. Hand-rolled schemes, ECB mode, static IVs and fast hashes used for passwords are each easy to miss in a running test and plain to see in the code.

  • Deserialization, template injection and code execution

    Sinks that turn input into objects, templates or commands: native object deserialization, server-side template rendering with user data, and the dynamic evaluation that gives an attacker a path to run code on the server.

  • Secrets, environment variables and logs

    Credentials committed to the source or its history, configuration values that leak through error pages and environment dumps, and log statements that write tokens, passwords or personal data where too many people can read them.

  • Dependencies, with reachability

    Third-party packages are checked against known vulnerabilities, and for the serious ones we trace whether your code actually calls the affected function. A vulnerable library on a path your code never reaches is a different priority from one it calls on every request.

A pattern catalog scoped to your team's idioms. Alongside the findings, we document the coding patterns we saw, safe and unsafe, in a form your developers can search for during pull request review and in CI. It often outlasts the individual findings, because it keeps catching the same mistake after the engagement ends.

Languages and frameworks we review regularly:

  • Java and Spring
  • Node.js with Express or NestJS
  • Python with Django or FastAPI
  • Go
  • Ruby on Rails
  • C# and .NET
  • PHP and Laravel

Less common stacks, such as Elixir, Rust, server-side Kotlin and Scala, have been reviewed in individual engagements. Tell us your stack and we will say plainly whether we are a good fit for it.

The OWASP Application Security Verification Standard (ASVS) is a useful yardstick for this kind of work: its requirements describe what sound authentication, access control, cryptography and error handling look like, and a review can be scoped against the parts that apply to your application.

03 / Method

How a code review runs, and where SAST fits

A scanner-only review is a tool dump; a review without one wastes reviewer hours on mistakes a machine can find. Five steps put each where it is strongest.

Show details for How a code review runs, and where SAST fits
  1. Step 1

    Repository onboarding and threat model

    We take repository access, build instructions and an architecture brief, then map trust boundaries, sensitive data flows and the dependency graph before reading any code in depth. The threat model decides where the reviewer's hours go.

    OutputThreat model and review plan

  2. Step 2

    Static analysis baseline

    A tuned static analyzer runs across the codebase to surface the cheap finds: hard-coded secrets, obvious injection sinks and calls to functions known to be dangerous. Its output is triaged by hand, and false positives are filtered out before anything reaches the report.

    OutputTriaged scan results

  3. Step 3

    Manual review, category by category

    The reviewer walks authentication, authorization, cryptography, deserialization, secret handling and dependency hygiene in turn, following data from where it enters to where it is used, and checks the scan's results against what the manual reading found.

    OutputConfirmed findings

  4. Step 4

    Pattern catalog

    The patterns behind the findings, together with the safe patterns your team already uses well, are written up as a catalog your developers can search for during pull request review and wire into CI.

    OutputSearchable pattern catalog

  5. Step 5

    Reporting and engineer pairing

    Findings are annotated with file, line and commit references and a code-level fix. Optional pairing sessions let your engineers walk through each fix with the reviewer before it ships.

    OutputAnnotated report and pairing sessions

Static analysis and manual review answer different questions, which is why the method uses both. In neutral terms:

Static analysis (SAST) and manual code review compared
QuestionStatic analysis (SAST)Manual review
How much code it coversEvery file, on every run, at the same depthThe paths the threat model ranks highest, read in depth
What it is good atShort data flows into known dangerous functions, hard-coded secrets, missing input validationAuthorization logic, business rules, flows spread across several requests, framework-specific traps
Where it strugglesBusiness logic, and data that passes through a cache, a queue or a database before it is usedRepeating the same depth on every commit, which is why its findings become rules and patterns
False positivesMany, unless the rules are tunedThe main cost of running itFew, because each finding is confirmed by reading the path
Where it fitsIn CI, on every pull requestBefore a release, after a rewrite, or where the risk is highest

Dynamic scanning and runtime instrumentation (DAST and IAST) watch the application while it runs, which makes them a separate exercise from reading the source. Where your pipeline should run each kind of automated check is a question for DevSecOps services.

04 / Common findings

Flaws a code review keeps finding

Four kinds of flaw recur across the codebases we read. Each is easy to write, easy to miss in a test that sees only responses, and clear once someone follows the input to where it lands.

Show details for Flaws a code review keeps finding
Flaws that recur in code reviews, and the fix the report supplies for each
FindingWhere it hidesSeverityWhat the report supplies
SSRF in URL-fetching codeImage proxies, webhook dispatchers and OAuth callback handlers that check a URL once and then fetch it. DNS rebinding, redirect chains and cloud metadata endpoints become reachable through them.VariesOften invisible from outside until the right URL is tried.The fetch call and the validation that precedes it, with an allowlist pattern that resolves and pins the address before the request is made.
Prototype pollution in deep-merge functionsVulnerable lodash versions, home-grown merge helpers and anything else that copies user input recursively into objects without rejecting __proto__. Gadgets that lead to remote code execution on the server can follow.VariesA Node.js finding that reads clearly in code.Every merge helper that accepts request data, and the key filter or safe library version that closes it.
Deserialization sinksJava native deserialization, Python pickle, PHP unserialize and Node node-serialize. Each one is a remote code execution primitive once user input can reach it.VariesReachability decides the rating.The call site, the route that feeds it, and a data format that cannot carry code.
ORM raw fragments and dynamic SQLSequelize literal(), Hibernate createNativeQuery, Django extra() and SQLAlchemy text(). Every ORM has an escape hatch, and developers reach for it when the framework cannot express what they need.VariesThe ORM gives no protection inside the escape hatch.Each raw fragment that takes input, rewritten as a parameterized query or mapped to an allowlist of columns.

How serious each one is depends on what the code protects and whether untrusted input can reach it, so the severity column reads Varies instead of naming one level.

05 / What you receive

What you receive from a code review

A code review report is written for the developer who has to open the file and change it. Every finding names the place, explains how input gets there and shows the corrected code; the executive report sums it up for the people who set priorities.

Show details for What you receive from a code review
  • An executive report for the people who decide priorities: what was reviewed, which findings carry the most business risk, and the effort needed to close them.
  • An engineering report with annotated findings, each tied to a file, a line and a commit, so a developer opens the exact place in the code.
  • A code-level fix for each finding, written for your code rather than a weakness ID and a link to a generic article.
  • The pattern catalog, ready to search for in pull request review and to turn into CI checks.
  • Committed secrets with their rotation status, from a scan of the repository history as well as the current branch.
  • A remediation matrix that ranks the findings and shows the order to fix them in.
  • Severity scoring: Code review findings are scored on CVSS 3.1, as in a penetration test.
  • Optional pairing sessions in which a reviewer walks your engineers through the fixes before they ship.

The sample VAPT report shows the layout of a complete BERRY9 report. Code review follows the same five phases as our other tests, described on the VAPT methodology page.

BERRY9 · ENGINEERING REPORTIllustrative sample

Finding F-02 · Code review

Sort parameter concatenated into a raw SQL fragment in the orders query

Severity
High
Location
repository.js, line 142
Reviewed at
Commit 4e1c9a2, main branch

How input reaches the sink

  1. OrdersController.list reads the sort value from the query string and passes it on unchanged.
  2. OrderRepository.find builds its ORDER BY clause with sequelize.literal() around that value.
  3. A sort value that carries a subquery reaches the database as SQL, outside the ORM's parameter binding.
// src/orders/repository.js, line 142 order: [sequelize.literal(`${sort} DESC`)]

Fix

Map the sort value to an allowlist of column names and pass only the mapped column to the ORM; never hand request input to literal().

Example layout, not client dataCWE-89 · SQL injection

06 / With testing

Code review alongside web, API and mobile testing

Reading the code and attacking the running application are complementary. Each tells you something the other cannot, and they can be scoped together.

Show details for Code review alongside web, API and mobile testing

A running-application test and a code review find overlapping but different flaws: the test shows what an attacker can actually do from outside, and the review shows why, and where else the same cause sits. A code review and a web, API or mobile test can share one proposal and one report.

All of these services sit together in our offensive security services overview.

07 / Your code

How your code is shared and handled

Handing over source code is a bigger step than handing over a URL, so the arrangements are agreed in writing before any repository is opened. Three things from you make the review possible; the fourth is yours to ask for.

Show details for How your code is shared and handled

What we need from you

  • Repository access to the code in scope, including its history.
  • Build instructions, so the dependency graph matches what you actually ship.
  • An architecture brief, even a short one, naming the services, data stores and trust boundaries.
  • A non-disclosure agreement, if you want one in place before the code is shared: NDAs are available on request.

Access. How the repository is shared is agreed at scoping.

Storage and deletion. Where the code is kept during the review, and when it is deleted, are agreed in writing before work starts.

Code and other material you share for an engagement is handled under your engagement agreement, not under the website's privacy notice, which covers inquiries sent through this site.

BERRY9 works from one office, in Hyderabad, and reviews are carried out remotely from there; on-site work is possible by arrangement.

08 / Price

What a source code review costs

A source code review starts from INR 27,000 + 18% GST. That is the starting figure: the price for your codebase is set after scoping, once its size, its languages and the depth of review you want are known, and larger codebases cost more.

Source code review

Starts fromINR 27,000 + 18% GST

Starting price; the figure for your codebase follows scoping.

Request a scoping call
  • How much code. A single service is a different job from a monorepo holding a dozen of them; the modules that handle sign-in, payments or personal data weigh most.
  • How many languages. Each language and framework brings its own dangerous functions and its own escape hatches, so a mixed stack takes longer to read than one written in a single language.
  • How deep. A review of the whole codebase, a review of selected modules, or a review of the changes since a given release each take a different amount of reviewer time.

Sizing: How a review is sized is set out in the proposal after scoping.

For ongoing review of pull requests after the engagement, separate retainer arrangements are available, set out in their own written proposal. How the price of a review compares with other tests is covered in the VAPT cost guide for India.

Working days for most code reviews
5 to 10
Code-review deliverables: annotated findings, pattern catalog, pairing sessions
3

The starting price for small scopes includes one free retest. For larger scopes, the retest terms are written into the proposal before work starts.

Code review by city

09 / Compliance evidence

Code review for SOC 2, PCI DSS and ISO 27001

Most frameworks speak about secure development in general terms, and a code review is one way to show it happens. How much weight the report carries is for your auditor or assessor to judge.

Show details for Code review for SOC 2, PCI DSS and ISO 27001

BERRY9 reviews code and does not act as an auditor or certification body for your organization. Whether a code review report counts toward a framework is your auditor's or assessor's decision, so their requirement is worth sending us before the review is scoped.

10 / Inquiry

Tell us about your codebase

Tell us what the application does, which languages and frameworks it uses, roughly how large the repository is, which parts worry you most, and your deadline. With that, we can suggest a scope and a timetable.

To talk it through first, call +91 86868 92922 or email contact@berry9.com.

Tell us what you need

Tell us what you need and when you need it. We will propose a scope and timeline.

Fields marked * are required.

What do you need?

What is in scope, and anything we should know about it. At least 20 characters.

We will respond within 24 hours.

11 / FAQ

Frequently asked questions

Short answers about scope, price and how testing works. For anything else, call +91 86868 92922.

What is the difference between SAST and manual code review?

SAST, static application security testing, is software that reads source code without running it and flags patterns known to be dangerous. It covers every file quickly and is good at short data flows, hard-coded secrets and unsafe function calls, but it produces false positives and cannot judge business logic or authorization rules. Manual review is a person reading the code paths that matter most, which finds logic flaws, chained issues and framework-specific mistakes a rule set cannot express. BERRY9 uses both: the scan for breadth, the reviewer for depth. See the section on How a code review runs, and where SAST fits above.

Which languages and frameworks do you review?

Regularly: Java with Spring, Node.js with Express or NestJS, Python with Django or FastAPI, Go, Ruby on Rails, C# and .NET, and PHP with Laravel. Less common stacks such as Elixir, Rust, server-side Kotlin and Scala have been reviewed in individual engagements. Tell us your stack and we will say honestly whether we are a fit.

Do we need to give you access to our repository?

Yes. A code review works from the source itself, so repository access is one of three things we ask for, together with build instructions and an architecture brief. If you want a non-disclosure agreement signed before the code is shared, NDAs are available on request. See the section on How your code is shared and handled above.

How much does a source code review cost in India?

A source code review starts from INR 27,000 + 18% GST. What you pay in the end depends on how much code is in scope, how many languages and frameworks it uses and how deep the review goes, and the figure is agreed in a written proposal once scoping is done. Reviews are carried out remotely from BERRY9's office in Hyderabad, for teams anywhere in India. See the section on What a source code review costs above.

How long does a secure code review take?

Most code reviews take 5 to 10 working days. A large repository, several languages or a deep review of every module takes longer, and the schedule is fixed in the written proposal before work begins. See the section on What a source code review costs above.

Should we get a code review or a penetration test?

They answer different questions. A penetration test shows what an attacker can do against the running application from outside; a code review shows the causes in the code, including flaws on paths a test never reached. A review suits code that is about to ship, has just been rewritten or handles payments and personal data; a test suits an application that is already live and exposed. The two can also be paired, with the test running white-box while the code is read.

Do you check our open-source dependencies?

Yes. Dependencies are reviewed against known vulnerabilities, and for high-impact ones, especially those pulled in indirectly, we check reachability: whether your code actually calls the vulnerable part. Knowing that a vulnerability exists somewhere in the dependency tree is much less useful than knowing whether your own code path reaches it.

Do you look for secrets in our git history?

Yes. The repository history is scanned for committed secrets, not just the current branch, and the report says whether each one has been rotated. A key deleted in a later commit is still exposed if anyone who should not have it ever cloned the repository.

Will you review our pull requests?

During the engagement, yes: we can pair with your engineers on specific pull requests, especially while findings are being fixed. For continuing review after the engagement ends, separate retainer arrangements are available.

What is a pattern catalog, and why does it matter?

It is a document of the coding patterns found in your code, the unsafe ones and the safe ones worth copying, written so your developers can search for them in pull request review and in CI. Every code review delivers one. It tends to be one of the most valuable parts of the engagement, because it keeps catching the same class of mistake long after the review is over.

Is a source code review enough for SOC 2 or PCI DSS?

It depends on the framework and on your auditor or assessor. PCI DSS 4.x has a requirement, 6.2.3, for reviewing bespoke and custom software before release, and a separate one, 11.4, for penetration testing, so a review and a test are different pieces of evidence. For SOC 2, whether a code review adds weight to the evidence is your auditor's call. BERRY9 reviews code and tests systems; it does not audit or certify.