SAST · SCA · Secrets · Manual review · OWASP Code Review · ASVS
Source code security audit
SAST + SCA + secrets detection + expert manual review on your repository. What the scanner sees and what only a human sees: authorisation logic, applied cryptography, environment configuration, supply chain, IaC. Every finding ships with file:line, fixed snippet and, where applicable, a proposed pull request ready to review.
Executive summary
A source code audit finds what an external audit (web, API) cannot see: faulty logic that runs but looks functional, misused cryptography that encrypts correctly with weak primitives, hardcoded secrets forgotten in Git history, vulnerable dependencies that the SCA scanner flags as critical but that are not exploitable in your context, environment configuration that opens doors without anyone noticing.
Typical Hard2bit projects close in 10 to 60 business days depending on volume. We combine SAST, SCA and automated secrets detection with expert manual review on the client's stack. Every finding ships with file:line, fixed snippet and, in many cases, a proposed pull request. Suitable to support PCI DSS, ISO 27001, ENS, NIS2 and DORA audits.
SAST + manual = real depth
The scanner amplifies coverage; the human validates and finds what only domain understanding can see. Without one of the two, the audit falls short.
Auditor-ready
Report designed to pass external audit: PCI QSA (req. 6.2.3/6.2.4), ISO certifier, ENS, NIS2, DORA, enterprise client requirements.
Practical remediation
When trivial, we bring a proposed pull request. When structural, detailed recommendation with example code. Not just generic descriptions.
What we cover in a code audit
The methodological baseline is OWASP Code Review Guide v2. We add ASVS L2/L3 verification, sector-specific controls and our own layered review pattern covering application code, infrastructure as code (IaC), CI/CD pipelines and dependencies.
Authentication and session
Login implementation, MFA, password recovery, token management (JWT/OAuth), expiry, regeneration, lockout, secure credential storage (bcrypt/argon2 with cost factor).
Authorisation and access control
Permission verification on every endpoint and operation, RBAC/ABAC implemented correctly, IDOR at code level, multi-tenant: tenant filter present in every query without exception.
User input and output
Input validation, prepared statements (no SQL concatenation), proper encoding on render (anti-XSS), safe parsing of XML/JSON/YAML, upload sanitisation, anti-deserialisation.
Applied cryptography
Modern algorithms (no MD5/SHA1/DES), secure randomness (not Math.random), proper IV/nonce management, correct padding, key storage separated from code.
Business logic
Validations living in the right place (not just on the client), approvals with privilege checks, race conditions, idempotency in financial operations, price/total/status manipulation.
Secrets management
Detection of secrets in code and full Git history, not only HEAD. Current validity check where feasible. Rotation recommendation with timeline.
Dependencies and supply chain
SCA with SBOM, real exploitability analysis of CVEs in your context, transitive dependencies, risk of low-maintenance packages, npm/PyPI typosquatting attacks, lockfile integrity.
Infrastructure as Code
Terraform/CloudFormation/Bicep: insecure configurations (public buckets, open security groups, encryption disabled), drift between IaC and real state, secrets in state files.
CI/CD pipelines
GitHub Actions/GitLab CI/Jenkins: token permissions, secrets manager, workflow escapes, execution of external PR code, supply chain of base Docker images.
Logging and auditing
Relevant security events get logged (login, privilege changes, sensitive data access), and sensitive data does NOT get logged (PII, tokens, passwords).
Environment configuration
Differences dev/staging/prod, debug enabled in prod, missing security headers per environment, CORS open in dev replicated to prod by mistake.
AI/LLM in code
If the code consumes LLMs: prompt injection, data leaks in system prompts, output validation before execution, secrets passed to the LLM without filtering.
Anatomy of a critical finding
Real technical pattern, anonymised: hardcoded secret in a mid-sized organisation's private repository, with derived risks: validity confirmed, 18-month exposure window, urgent rotation procedure.
Discovery
Payment gateway API key in src/config/stripe.ts
Gitleaks flagged the pattern on line 14 of src/config/stripe.ts:
const STRIPE_KEY = "sk_live_...". Git history review
showed the commit that introduced the secret was 18 months old. The later
substitution by process.env.STRIPE_KEY did not remove the
secret from history. The repository was private but accessible to 23 active
employees, 4 ex-employees and one external supplier.
Severity
CVSS 4.0 = 9.6 + 18-month window
Passive verification confirmed the key was still valid with production permissions. Potential impact: charge issuance, refunds, transaction history access, possible customer enumeration. 18-month exposure window with 28 people having access to the repository at some point in that period. Additional regulatory risk: if the 4 ex-employees kept local clones, exposure becomes indefinite.
Evidence
Traceable documentation
Capture of the file in the original commit, of the commit that attempted to remove it (showing it only changed current code, not history), of the Gitleaks output with the secret's fingerprint, and of the validity check (no data extracted, only confirming the account info endpoint returned 200 OK). List of identities with repository access during the window.
Remediation
Urgent rotation + history cleanup
Immediate (2 hours): key rotation on the gateway, deployment with the new key
via secrets manager. Medium term (1 day): Git history purge with
git filter-repo, force-push, notification to all
collaborators to re-clone. Long term: pre-commit hooks with Gitleaks on every
development machine, blocking scan in CI, documented secrets management policy
and developer training.
Anonymised technical case based on real patterns. Sector and names altered; the technical pattern and the remediation procedure stay faithful to the original. No NDAs disclosed, no client name.
When it fits and when it does not
Fits very well
When it is worth it
- SaaS product, in-house software, fintech, healthtech, software factory
- Application with payment module, special category data or critical flows
- Auditor requires evidence (PCI DSS, ISO 27001, ENS Alta, NIS2, DORA, enterprise client)
- Change of development team: inherit with a known baseline
- Post-incident suspected of code origin
- After a web/API audit with many findings: to find the root cause
- Before migrating to cloud or entering regulated markets
Fits less well
When it is not the first move
- Product mostly built on third-party SaaS services (little proprietary logic)
- Code under major refactor: any finding changes within weeks
- If you only need to validate external behaviour: web audit or API audit are more efficient
- Immediate post-incident response needed: incident response first; audit afterwards
- Development team without code review practice yet: implant internal process before auditing
How we deliver
Four real phases. The difference with a standard SAST provider is that the client receives findings with context and, where viable, proposed corrected code.
1. Walkthrough and setup (1-3 days)
Session with tech lead or senior developer. We understand architecture, critical modules, languages, frameworks, deployment model. We agree code access mode (local clone under NDA, client VDI, physical isolation). We configure SAST/SCA/secrets adapted to the stack and run the first automated pass.
2. Expert manual review (60-75% of time)
Auditor with stack experience reviews SAST findings (filtering false positives), manually audits critical modules (authentication, authorisation, cryptography, integrations, IaC), validates business logic with the code in hand. Critical findings get notified immediately, not kept.
3. Documentation and PR proposals
Every finding with file:line, original snippet, fixed snippet, CVSS 4.0, impact, exploitation conditions. For findings whose remediation is trivial we prepare a proposed PR on a feature/security-audit-fixes branch that the development team can review and apply directly.
4. Closure and revalidation
90-minute session with tech lead and senior developers to discuss findings, remediation plan, real prioritisation. If revalidation is contracted, second pass 4-8 weeks later verifying that the fixes work, with a signed verification letter for external auditors.
What the documentation package includes
1. Technical report
Each finding with file:line, original snippet, fixed snippet, CVSS 4.0, impact, exploitation conditions, detailed recommendation.
2. Executive report
2-3 pages without technical jargon for the board. Findings in business terms, aggregated risk, action plan.
3. Prioritised matrix
Findings ordered by real risk: severity + exposure + exploitability + effort. Actionable list for sprint planning.
4. Proposed pull requests
For trivial findings (60-70%): PR already written on feature/security-audit-fixes branch ready to review and merge. Accelerates remediation.
5. SBOM + SCA report
Complete dependency inventory with SBOM in CycloneDX/SPDX format, CVEs per dependency with exploitability analysis.
6. Evidence repository
Signed ZIP with timestamps, output of SAST/SCA/secrets tools, screenshots, audit logs. Suitable for external auditors.
Adaptation by sector
B2B SaaS and software factory
Focus on multi-tenant, object-level authorisation in code, secrets, dependencies, IaC. Compatible with SOC 2 where applicable. Typical product needs to report evidence to enterprise clients.
Fintech and financial entities
PCI DSS 6.2.3/6.2.4 if CDE is touched, DORA art. 24-27. Intensive focus on cryptography (password hashing, PII encryption, key management), payment flows, fraud prevention, race conditions in transfers.
Healthtech
GDPR art. 9 (special category data), HL7/FHIR integrations. Focus on medical role authorisation, complete audit logging of clinical record access, encryption at rest and in transit, retention and secure deletion.
Public sector and government services
ENS by categorisation. Focus on compliance, accessibility (WCAG), identity with Cl@ve, storage and deletion in line with legislation, traceability for administrative auditors.
Retail and e-commerce
PCI DSS if payments are touched. Focus on cart and pricing logic (manipulation), fraud prevention, coupon abuse, stock race conditions, payment gateway integrations.
Embedded / IoT with backend
Focus on firmware and associated backend: secure OTA management, device authentication, communications encryption, secure key storage on device, server-side validation.
Regulatory fit
| Framework | Reference | What it requires and how we cover it |
|---|---|---|
| PCI DSS v4.0.1 | Req. 6.2.3 and 6.2.4 | Code review of applications that touch the CDE before production and after significant changes. Suitable for PCI QSA. |
| ISO 27001:2022 | A.8.29 / A.8.28 | Security testing in the development lifecycle + secure coding principles. Traceable evidence for certification. |
| ENS (Alta) | op.exp.2 / op.exp.5 | Vulnerability analysis in the lifecycle and periodic technical testing. Suitable for ENS audit. |
| NIS2 | Art. 21.2.f | Policies and procedures to assess the effectiveness of measures. Documented periodicity and traceability. |
| DORA | Art. 9 + 24-27 | ICT risk management in applications and digital resilience testing programme. Suitable for the financial supervisor. |
| Executive Order 14028 (SBOM) | US federal mandate / NIS2 / DORA | SBOM in CycloneDX/SPDX for clients selling to US public sector or regulated EU entities. |
| GDPR | Art. 32.1.d | Regular verification of the effectiveness of technical measures. Especially relevant where special category data is involved (art. 9). |
What we tend to do and others do not
Proposed pull requests
For trivial findings (60-70%) we bring a PR already written ready to review. Accelerates remediation from weeks to hours.
Full Git history for secrets
Many auditors scan only HEAD. We review the full history: 70% of live secrets sit in old commits the team assumed 'removed'.
Secret validity verification
Where feasible and ethical, we passively check whether the secret is still active. Drastically changes remediation priority.
CVE exploitability analysis
We do not just list Snyk or Dependabot CVEs. We verify whether the vulnerable path is invoked from your code. 30-50% are not exploitable in context.
IaC review
Terraform, CloudFormation, Bicep: this is where public buckets, open security groups, secrets in state files leak. Many auditors focus only on application code.
Auditor with the client's stack
An auditor who knows Java audits Java. An auditor who knows Go audits Go. We do not assign a generic-pattern auditor to a Rust project.
Objections we hear and how we answer
«We already run Sonar/Snyk in CI, we do not need an audit»
Sonar and Snyk are excellent tools for breadth and to stop regressions, but neither finds faulty logic, contextual misuse of cryptography, or secrets in Git history that these scanners do not traverse. An expert manual audit complements, not replaces, that automated layer.
«Our code is very specific, you will not understand it»
The initial technical walkthrough exists exactly for that. If after the walkthrough the auditor believes the stack is outside their comfort zone, we will tell you honestly and refer the project or step aside. We never accept audits we cannot do well.
«Our code is our most sensitive asset»
We work under a standard NDA, with local clones on encrypted workstations (no cloud), and a wipe certificate at close. For especially sensitive environments we offer VDI mode on the client's infrastructure or onsite physical isolation. Code is never reused.
«It is expensive. A one-off audit does not scale»
That is why we deliver proposed PRs where we can: we turn findings into applicable code. And we always propose at close how to integrate what was learnt into CI (custom Semgrep rules, review policy, team training). The audit is not just a report, it is knowledge transfer.
«We have millions of lines, do you audit everything?»
No. We audit what is critical with depth and apply SAST/SCA to everything. On large projects the proposal is: exhaustive manual review of authentication, authorisation, cryptography, payment and integration modules; SAST/SCA on the rest; selective analysis of areas the SAST flags as high risk density.
«If you find many things, is that good or bad?»
It is expected and it is good. An audit that finds nothing in a real project means insufficient coverage or an auditor who does not understand the domain. What matters is: are the findings actionable? Is remediation viable? Is the real risk proportionate to the effort to fix it?
How we measure the quality of our code audits
Six internal indicators benchmarked against our own history. Shared in the closing session.
Lines/day per auditor
Productivity. Too many LOC/day suggests superficial review; too few suggests inefficiency.
SAST false positive ratio
Percentage of scanner hits we discard after manual review. Target: <40% (we deliver verified findings, not raw output).
ASVS coverage
Percentage of ASVS L2/L3 controls verified in code. Target: 100% on critical modules.
Proposed PRs / trivial findings
Percentage of trivial findings where we contribute a PR. Target: >65%.
Time to critical notification
Hours from critical finding detection to client notification. Target: <8 business hours.
Revalidation closure rate
Percentage of findings the client actually closes by revalidation. Indicator of recommendation quality.
Common mistakes when buying a code audit
- Asking for 'a Sonar pass' and calling it an audit. It is a first automated filter, not a review. Without the manual layer, you miss business logic and misapplied cryptography.
- Not auditing Git history for secrets. 70% of live secrets sit in old commits the team assumed were removed.
- Accepting a CVE list without exploitability analysis. 30-50% of CVEs reported by SCA are not exploitable in context; spending time remediating them is cost without return.
- Ignoring IaC. Public buckets, open security groups, keys exposed in Terraform state are typical findings that do not show up in application code.
- Trusting only the generic auditor. Auditing Java with an auditor who only knows Python leaves enormous gaps. Ask for the auditor's profile before signing.
- Not revalidating after remediation. Without a second pass, the report does not serve external auditors.
- Leaving the audit until the end of the release. Finding critical issues a week before going live breaks the roadmap. Better to anticipate.
- Not integrating what was learnt into CI. Without custom Semgrep rules + review policy, the same mistakes will return in the next release.
Quick glossary of code audit jargon
SAST
Static Application Security Testing. Static code analysis without executing it. Detects known unsafe patterns.
SCA
Software Composition Analysis. Analysis of third-party dependencies and libraries. Detects CVEs and licence issues.
SBOM
Software Bill of Materials. Inventory of software components. CycloneDX and SPDX are the standard formats.
DAST
Dynamic Application Security Testing. Dynamic analysis (on the running app). Complementary to SAST.
OWASP Code Review Guide
OWASP reference guide for code review. Version 2 published in 2017, under continuous revision.
OWASP ASVS
Application Security Verification Standard. Levels L1, L2, L3 by criticality.
Secrets scanning
Automated detection of hardcoded secrets in code and configuration files. Tools: TruffleHog, Gitleaks, Semgrep.
Pre-commit hooks
Scripts that run before each local commit. Useful to block secrets and typical mistakes before they reach the repo.
IaC
Infrastructure as Code. Terraform, CloudFormation, Bicep, Pulumi. Audit infrastructure configurations as if they were code.
Supply chain attack
Compromise of a third-party dependency that propagates to whoever uses it. Recent cases: npm easy-day-js, Codecov, SolarWinds.
Pull request
Request to merge changes in a Git repo. Natural point for code review and for audit-proposed PRs.
False positive
Scanner finding that after human analysis turns out not to be exploitable or not to apply. Manual review filters them out.
Related services at Hard2bit
Pentesting
Parent service. Code audit is the white-box discipline within enterprise pentesting.
View →
Web application audit
Complementary. Web tests behaviour from outside; code tests the internal implementation. Combined, full coverage.
View →
API security audit
If your API is central, combine with a code audit of the backend serving it.
View →
Non-human identities
Where we find most hardcoded secrets: tokens, API keys, certificates embedded in code.
View →
Third-party risk management
Software supply chain is third-party risk: programme to manage it.
View →
Attack surface management
Continuous monitoring: detect newly exposed public repositories, leaked secrets, post-release exposure.
View →
Integrated audit
When scope also includes infrastructure, identity, cloud and processes: a single project.
View →
Vulnerability management
CVEs detected in dependencies are managed in the client's vulnerability management programme.
View →
Incident response
If the audit reveals active compromise (backdoor, secret leaked in use), escalation to response.
View →
Frequently asked questions
What is the difference between automated SAST and manual code audit?
SAST (Static Application Security Testing) scans the code looking for known patterns: unsafe function calls, weak configurations, vulnerable libraries, hardcoded secrets with detectable format. It is fast, cheap and integrates into CI/CD, but it generates many false positives and misses logic flaws that require understanding the domain. Manual auditing brings what no scanner sees: badly designed authorisation logic, race conditions, implicit trust assumptions between components, misuse of cryptography that the scanner marks as green, abuse of legitimate flows. Combining both is the standard: SAST for breadth, humans for depth.
What tooling and methodology do you follow?
We combine several layers. SAST with SonarQube/Semgrep/CodeQL adapted to the client's stack. Software Composition Analysis (SCA) with Snyk/OSV-Scanner/Trivy for dependencies and SBOM. Secrets detection with TruffleHog/Gitleaks. On top of that we apply the OWASP Code Review Guide v2 as methodological baseline, OWASP ASVS L2/L3 for verification, and our own review pattern covering authentication, authorisation, session management, applied cryptography, input handling, output (XSS), third-party integrations, environment configuration, IaC (Terraform/CloudFormation/Bicep), CI/CD and supply chain. The team is built with engineers experienced in development on the client's stack, not just generic security auditors.
How long does a code audit take and how much does it cost?
It depends heavily on size and complexity. A medium repository (40-80k lines of code, single stack, single development team) is audited in 10-20 business days with 1-2 auditors. Indicative cost: €12,000-28,000. Large monorepos (200k+ lines, multiple services, IaC, multiple languages) take 30-60 days and €40-90k. Before quoting we request read access to the repository to make an initial inventory: languages, frameworks, dependencies, indicative cyclomatic complexity. Without that, any number is made up.
Do you need full access to the code? How is confidentiality managed?
Yes, read access to the repository. We prefer to work on a local clone on encrypted workstations with a signed NDA, with nothing uploaded to the cloud. If the client prefers we work in their environment (clientless via corporate VDI, internal repository with temporary access), that is also viable. Code is never shared with third parties, never reused in other audits, and is wiped from our workstations at project close with a signed wipe certificate. For especially sensitive environments (defence, critical infrastructure) we can work in physical isolation on client premises.
Do you audit only mainstream languages or also niche stacks?
We audit the stack the client uses. Mainstream: Java, .NET, Python, Node.js/TypeScript, Go, Ruby, PHP, Kotlin, Swift. Frontend: React, Vue, Angular, Svelte. Backend: Spring, ASP.NET, Django, FastAPI, Express, NestJS, Laravel. IaC: Terraform, CloudFormation, Bicep, Pulumi. More specific: Rust, Elixir, Scala, Clojure, legacy COBOL in banking. If the client works with very vertical stacks (proprietary languages, embedded industrial), we assess in the walkthrough whether our team is the right fit or whether a specialised partner is more appropriate. We never accept a project on a stack we cannot handle well, to avoid disappointing the client.
What deliverables do you provide at the end of the project?
Four pieces. Technical report with each finding (file:line, original snippet, fixed snippet, CVSS 4.0 severity, exploitation context). Executive report of 2-3 pages. Risk-prioritised matrix (not only CVSS: considers exposure, exploitability and remediation effort). Proposed pull requests in GitHub/GitLab/Bitbucket for critical findings whose remediation is trivial (we estimate 60-70% of findings). Close session with development. If revalidation is contracted, a second pass that verifies the fixes and produces a verification letter suitable for external auditors.
Does it serve as evidence for PCI DSS, ISO 27001, ENS or NIS2?
Yes. PCI DSS v4 (req. 6.2.3 and 6.2.4) requires code review of applications that touch the CDE, before production and after significant changes. ISO 27001:2022 (A.8.29) requires security testing within the development lifecycle, where code review is one of the components. ENS Alta (op.exp.2 and op.exp.5) requires vulnerability analysis in the lifecycle. NIS2 (art. 21.2.f) requires policies and procedures to assess the effectiveness of measures. DORA (art. 9 and 24-27) covers resilience testing. The report is delivered ready to support an external audit.
Do you find hardcoded secrets? It seems very frequent.
Almost always. We combine Gitleaks/TruffleHog across the full Git history (not just HEAD) with manual review of patterns scanners miss: secrets in comments, base64 encoded, split across constants, in .json/.yaml/.properties files not scanned by default. Reported secrets come with two extras that few auditors do: confirmation of whether the secret is still valid (with passive verification against the relevant provider where feasible and ethical), and rotation procedure with the secret's time fingerprint in the repo so the client can calculate exposure window.
What do you do with vulnerable dependencies? Is it just listing CVEs?
No, that is what a basic SCA scanner does, and what the client can get for free with Dependabot or Renovate. What we add is prioritisation by real risk, not theoretical CVSS: is the dependency used or sitting as an inactive transitive? Is there an exploitable path from client code, or is the vulnerable component only invoked in safe contexts? Is there a stable patch or only a workaround? Is there a substitute version without breaking changes? The client receives the list prioritised by real exposure plus update recommendations: in general, 30-50% of CVEs reported by SCA in real projects are not exploitable in the specific context.
How do we start a project with Hard2bit?
A 30-minute call to understand the repository, the stack, the deployment model, the moment in the lifecycle (release, post-incident, regulatory requirement) and the objective. If it fits, a 1-2 hour technical walkthrough with a developer to understand architecture, critical flows and the highest-risk areas. From there we issue a firm proposal in 48-72 hours: scope, window, assigned team, deliverables and fixed price. No commitments until signature. If after the walkthrough we think the project needs to be split into phases or that it makes sense to combine with a web/API audit, we will say so honestly.
Does your code need a serious audit?
30-minute call to understand the repository, the stack and the objective. If it fits, firm proposal in 48-72 hours. No commitments until signature. Standard NDA before any code access.