Security audits
Application security audit
We read the code that decides who can do what, and the pipeline that ships it.
Where a penetration test probes the running application from outside, this review works from the source. Reviewers trace how authentication, authorisation, input handling, cryptography and secrets are implemented, check the dependencies and the build and deployment pipeline, triage what static analysis reports, and review the hot spots by hand. Findings are mapped to the OWASP ASVS 5.0 level you choose, so you finish with a verified baseline you can show a customer or an auditor.
- Best for
- Engineering teams whose product handles money, personal data or other tenants' data, who need assurance deeper than a time-boxed external test, evidence of secure development for enterprise buyers, or a baseline before a major release.
- Duration
- 5 to 15 working days, depending on codebase size
- Standards
- OWASP ASVS 5.0
- OWASP API Security Top 10 (2023)
- OWASP Top 10 CI/CD Security Risks
- NIST SP 800-218 (SSDF)
- SLSA (Supply-chain Levels for Software Artifacts)
Signals you need this now
- An enterprise customer's security questionnaire asks for evidence of secure code review alongside the penetration test letter.
- A penetration test came back clean, but authorisation is enforced handler by handler across hundreds of endpoints that no time-boxed test could cover.
- Static analysis runs on every pull request, but its results are suppressed in bulk or never opened, so a real injection flaw would pass with the rest.
- Secrets, signing keys or cloud credentials were committed to the repository at some point, or its history has never been scanned to rule that out.
- A pull request, a third-party action or a self-hosted runner can trigger a deployment to production.
- You place software on the EU market and need to show how you find and handle vulnerabilities: the Cyber Resilience Act's reporting obligations have applied since 11 September 2026.
- The product was built quickly, by a small team or an outsourced vendor, and nobody independent has read the code.
How the audit runs
Read-only by default and in this order, with a short written update at the end of each day and an immediate call if anything critical turns up.
- 1
Architecture and threat-model review
We start with your engineers: data flows, trust boundaries, identity, tenancy and the assets an attacker would want. If you have a threat model we test it; if not, we build a lightweight one together. It decides where the manual review time goes.
- 2
Agree the ASVS level
The OWASP ASVS 5.0 level is agreed with you at scoping and confirmed here against the threat model. Requirements that do not apply to your stack are recorded as not applicable, with the reason.
- 3
Automated coverage, triaged by hand
Static analysis (SAST), software composition analysis and secrets scanning run across the repository and its full history. Every result we report has been read and confirmed by a person; the rest are recorded as triaged, so your team does not repeat the work.
- 4
Manual review of the hot spots
Reviewers read the code that makes security decisions: authentication, authorisation and tenant isolation, input parsing and deserialisation, file handling, cryptography, and the logic that moves money or grants entitlements. Suspected issues are confirmed against a running instance where you provide one.
- 5
Pipeline and infrastructure review
We follow code from merge to production: branch protection, CI permissions, third-party actions, runners, artefact signing, infrastructure as code, and the secrets each stage can reach.
- 6
Report, walk through and retest
Findings carry file and line references, the reasoning or proof behind their exploitability, and a fix in your language and framework, alongside an ASVS coverage matrix. We walk the owning engineers through them, then run the free retest of every fixed finding within 30 days of report delivery and reissue the report.
What we check
Grouped as they appear in the report. The scoping call settles which groups apply to you.
Architecture and threat model
- Trust boundaries, data flows, and where authentication and authorisation decisions are made in the code
- The tenant isolation model (separate databases, schemas, row-level security or application checks) and how it fails
- Internal services, queues and webhooks that trust their callers without authenticating them
- Abuse cases for the features that move money, data or entitlements
Authentication and authorisation implementation
- Login, MFA, password reset, magic links and account recovery, each read in the code that implements it
- Session and token handling: lifetimes, revocation, refresh-token rotation, and JWT verification of signature, algorithm, issuer, audience and expiry
- OAuth and OpenID Connect flows: exact redirect URI matching, state and PKCE, and where tokens are stored
- Authorisation enforced on every route and object through a central mechanism, with tests that prove it
- Admin, support-impersonation and internal endpoints, and the feature flags that expose them
Input and output handling
- Injection traced from source to sink: SQL, NoSQL, OS command, template, LDAP and expression languages
- Output encoding for each context, with the templating or front-end framework's escaping left on
- Deserialisation, XML parsing, file uploads, archive extraction and image or document processing
- Server-side request forgery in webhooks, link previews, importers and PDF generators
- Mass assignment and over-posting in models and API handlers
Cryptography in use
- Algorithms, modes and key lengths checked against ASVS V11 Cryptography: no insecure block modes such as ECB or weak padding such as PKCS#1 v1.5, no MD5 or other disallowed hash for any cryptographic purpose, and no home-grown cryptography
- Password storage with Argon2id, scrypt, bcrypt or PBKDF2 at work factors no lower than the OWASP Password Storage Cheat Sheet recommends
- Tokens, identifiers and secrets generated from a cryptographically secure random source
- Key management: where keys live, who can use them and how they rotate
- Certificate verification left on in every HTTP client, SDK and database driver
Secrets management
- Secrets scanning across every commit in the repository's history
- Runtime secrets fetched from a secrets manager, with none baked into images
- Scope and rotation of API keys, signing keys and cloud credentials
- Secrets leaking into logs, error reports, front-end bundles and mobile builds
Dependencies and software composition analysis
- Direct and transitive dependencies matched against known vulnerabilities and triaged by whether your code can reach the vulnerable function
- Lockfiles committed and honoured in CI, with no floating versions in production builds
- Abandoned, typo-squatted or suspiciously new packages, and install-time scripts
- A software bill of materials (SBOM) that the build can regenerate on demand
Build and CI/CD pipeline
- Branch protection and required review on every branch that deploys
- Workflow tokens scoped to the minimum, and secrets withheld from builds of pull requests from forks
- Third-party actions and plugins pinned to full commit hashes, since tags can be moved
- Self-hosted runners isolated and ephemeral, with artefacts signed and build provenance recorded
- Short-lived deployment credentials, through workload identity federation where the platform supports it
Logging and error handling
- Security events logged: logins and failures, privilege changes, access denials and high-value actions
- No passwords, tokens or unnecessary personal data in logs
- Errors that fail closed and never return stack traces or internals to users
- Logs protected from tampering and retained long enough to investigate an incident
Infrastructure as code
- Terraform, CloudFormation, Kubernetes manifests and Helm charts reviewed for exposure and excess privilege
- Container images: base image currency, processes running as root, and secrets left in layers
- Network policies, security groups and public endpoints in code compared with what was intended
- Drift between what the code declares and what is actually deployed
API design
- Object-level and function-level authorisation on every endpoint, mapped to the OWASP API Security Top 10 (2023)
- Schema validation, pagination limits and rate limiting on every public operation
- GraphQL introspection, query depth, cost and batching limits
- Old API versions and deprecated endpoints that still answer
- Webhooks signed, verified and protected against replay
OWASP ASVS 5.0 mapping
- Target level agreed against data sensitivity and user expectations, with the reasoning recorded
- Coverage across all 17 chapters, from V1 Encoding and Sanitization to V17 WebRTC
- Each requirement marked met, not met, not applicable or not verified, with evidence
- Gaps converted into backlog items your team can track to closure
SAST triage and manual hot spots
- Your existing scanner results imported and triaged, or ours run where you have none
- False positives recorded with the reason, so they can be suppressed safely
- Custom rules written for the patterns we find, so the same bug is caught in future pull requests
- Manual review time weighted towards the code the threat model marks as critical
What we find most often
Anonymised patterns that recur in audits of this kind, with the severity they usually carry and the change that closes each one.
Critical Authorisation enforced only in the interface
Controls are hidden from users without permission, but the API endpoints behind them accept the request from any authenticated user, including users in other tenants.
Fix: Enforce authorisation server-side through one policy layer, and add tests that call each endpoint as the wrong user and from the wrong tenant.
Critical Signing key in the repository
The key that signs session tokens or webhooks was committed early in the project, so anyone with read access to the code, or a leaked copy of it, can mint valid tokens.
Fix: Rotate the key, invalidate tokens signed with the old one, load keys from a secrets manager and scan every pull request for secrets.
High Tokens decoded without verification
JWTs are decoded without verifying the signature, or the algorithm is taken from the token header, so a forged or unsigned token is accepted.
Fix: Verify with a maintained library, pin the expected algorithm and key, and check issuer, audience and expiry on every request.
High Pipeline secrets reachable from pull requests
Workflows that run on pull requests from forks can read deployment secrets, or third-party actions are referenced by a tag their owner can move to new code.
Fix: Withhold secrets from untrusted builds, pin actions to full commit hashes and give each workflow the minimum token permissions.
High Server-side request forgery through a convenience feature
A link preview, PDF renderer or webhook tester fetches any URL it is given, including the cloud metadata service and internal admin panels.
Fix: Validate destinations against an allow-list after resolving them, block private and link-local ranges, and route outbound fetches through an egress proxy.
Medium Mass assignment on account updates
The update handler binds the whole request body to the model, so a user can set fields such as role, plan or tenant identifier that the interface never shows.
Fix: Bind only an explicit list of permitted fields for each operation, and test that the protected fields are refused.
Medium Untriaged dependency alerts
Hundreds of open dependency alerts, most unreachable and a few critical, with no way to tell which is which, so the critical ones age alongside the noise.
Fix: Triage once for reachability, set a fix window by severity, and fail the build only on new, reachable, high-severity issues.
Low Debug output in production
Framework debug pages or stack traces reveal file paths, library versions and queries, which tell an attacker which known exploits to try first.
Fix: Disable debug modes in production builds, return generic errors to users and keep the detail in server-side logs.
What you receive
- Executive summary: overall posture, the few issues that matter most, and the ASVS level achieved against the level targeted
- Findings with file and line references, exploitability reasoning or proof, CVSS 4.0 severity adjusted for business context, and a fix in your language and framework
- OWASP ASVS 5.0 coverage matrix with evidence for every requirement in scope
- Triaged static-analysis, dependency and secrets-scanning results, with false positives documented
- Pipeline and infrastructure-as-code hardening plan ranked by effort against risk
- Custom detection rules for the bug classes found, ready to run in your CI
- Walkthrough with the engineers who own the code, and a free retest of every fixed finding within 30 days of report delivery, with the report reissued
Scan, audit, penetration test or red team?
Four kinds of assessment that are often confused. They answer different questions, and most security programmes need more than one.
The tinted Security audit column is the service on this page. Scroll the table sideways to compare all four.
| Dimension | Vulnerability scan | Security audit | Penetration test | Red team |
|---|---|---|---|---|
| Purpose | Find known vulnerabilities and misconfigurations quickly and repeatedly. | Measure configuration, code and controls against a named standard, and prove each result with evidence. | Show what an attacker can achieve within a defined scope. | Test whether your people, detection and response stop a realistic adversary pursuing an objective. |
| Method | Automated tools matching signatures and versions, with no human judgement unless someone triages the output. | Read-only review of settings, grants, code and evidence, with tools for coverage and people for judgement. | Manual, adversarial testing that chains weaknesses together, with automation used only for coverage. | A covert, objective-led campaign across technical and human attack paths, run against live defences. |
| Depth | Broad and shallow: everything it can reach, nothing it cannot recognise. | Broad and deep on configuration: every instance, setting and control in scope. | Deep on exploitable paths within scope; less exhaustive on configuration. | Narrow and deep: a few paths to one objective, followed as far as they go. |
| Access needed | Network reachability, plus credentials for authenticated scans. | Read-only accounts, configuration exports, repositories or dashboards that you grant. | Test accounts and an agreed scope; sometimes source code or architecture notes. | A signed objective and a small group who know; as little insider information as possible. |
| What you receive | A machine-generated list, often long, ranked by generic severity. | Ranked findings mapped to the standard, each with the setting or line to change, plus a coverage matrix. | Exploited findings with reproduction steps, evidence, business impact and fixes. | An attack narrative and timeline set against what your team detected, missed and how quickly it responded. |
| Typical duration | Minutes to hours, repeated on a schedule. | Three to fifteen working days, depending on the estate or the codebase. | One to two weeks for most single applications or networks. | Several weeks, including planning and the debrief. |
| Best when | You need continuous hygiene between deeper assessments. | You need assurance against a standard, a baseline before testing, or evidence for a customer or an auditor. | You need to know whether an attacker can get in or escalate, before a launch or a deal. | You have a working security function and want to know whether it holds under pressure. |
| Standards | Vulnerability feeds identified by CVE and scored with CVSS. | OWASP ASVS 5.0, CIS Benchmarks, PCI DSS v4.0.1 and vendor hardening guides. | PTES, NIST SP 800-115, the OWASP Web Security Testing Guide and MITRE ATT&CK. | MITRE ATT&CK and threat-led frameworks such as TIBER-EU. |
| What it will not tell you | Whether a finding is exploitable, or anything about business logic and access control. | Whether a determined attacker can chain the gaps together; that is the test's job. | Whether your team would detect and contain the attack while it is happening. | Every weakness in scope: it follows the shortest path to its objective. |
Questions buyers ask
How is an application security audit different from a penetration test?
A penetration test works from outside, against the running application, within a fixed time, and proves what an attacker can do. A code-assisted audit reads the implementation, so it finds the flaw in the one handler a test never reached, and explains why a class of bug exists instead of reporting each instance. They work well together: the audit first, then a web application test aimed at what the code review flagged.
Do you need our source code, and how is it handled?
Yes: read access to the repositories in scope, ideally through a named, time-limited account on your own platform so nothing is copied. If code must leave your environment, it is held encrypted, used only for the engagement and destroyed on the schedule you set.
Which ASVS level should we aim for?
Level 2, for most products that hold personal data, payments or other tenants' data: ASVS says most applications should be striving to achieve it. Level 1 holds the minimum requirements, and ASVS gives an early-stage startup collecting little sensitive data as one that might start there. Level 3 is the goal for applications looking to demonstrate the highest levels of security; ASVS's example is a bank's online banking application. ASVS leaves the choice to you, so we recommend a level during scoping and record the reasoning, which makes it defensible to a customer or an auditor.
We already run SAST and dependency scanning. What does this add?
Tools match patterns; they rarely understand your authorisation model, your tenancy or your business rules, which is where the serious flaws sit. We triage what your tools already report, confirm the real issues, and spend most of the review on the code no rule covers.
How do you match a reviewer to our stack?
Tell us your languages, frameworks and infrastructure tooling on the scoping call. We confirm we have a reviewer for that stack before quoting, and if someone else would serve it better, we will say so.
Does the audit help with the EU Cyber Resilience Act?
If you place software products on the EU market, the Act's reporting obligations have applied since 11 September 2026 and its main obligations apply from 11 December 2027. An audit gives you evidence for the product-side work, such as review against a recognised standard, an SBOM you can regenerate and a vulnerability handling process that has been exercised, but it does not replace a conformity assessment. The compliance overview covers scope and dates.
Will you fix the issues for us?
No. Each finding comes with a fix written for your language and framework, we answer your engineers' questions while they build it, and we retest it once it lands. Your team makes the changes, so it keeps ownership of the code and knows why each change was made.
Scope your application security audit
A 45-minute scoping call ends with a fixed quote and a proposed start date; the written scope follows by email. On the call we agree the estate, the standard and the access.