Semgrep
Vulnerable code patterns — injection, unsafe auth logic — on every commit.
Case study
Before we sell a security-first sprint, we run the exact same toolchain against our own production build — a payments-enabled booking marketplace. Here's what it found, what was already right, and what we fixed. Reports and commits included.
The build
Two-sided marketplace: OTP phone login, service scheduling, Razorpay payments, real-time booking updates, and an admin back office. Built on the sprint's default stack — Next.js and NestJS in TypeScript, PostgreSQL and Redis, Docker behind nginx. Built fast, then taken through the security pipeline. This case study is the "then."
The pipeline
The same suite that ships in every sprint — wired into GitHub Actions so it re-runs on every push, not just once.
Vulnerable code patterns — injection, unsafe auth logic — on every commit.
Scans the full git history for keys and credentials, not just the latest commit.
Known-vulnerable packages across both frontend and backend.
CVEs, secrets, and Dockerfile / compose misconfigurations.
Scans the actual container images that would ship to production.
Probes the live staging app the way an attacker would.
Where things ran: Gitleaks, Trivy (filesystem + config), and npm audit ran directly against the code. Semgrep, the Trivy image scan, and the ZAP baseline run on the Linux CI runner — wired into the pipeline rather than run by hand, so they fire on every future push too.
What the scan found
Both the frontend and backend Docker images ran as root. If an attacker ever got code execution inside a container, root widened the blast radius. Now both drop to an unprivileged user; the images re-scan clean.
Neither image told the orchestrator whether it was actually healthy. Both now probe a real endpoint, so a hung container gets restarted instead of quietly serving errors.
Two frontend packages pulled in indirectly by the framework carried moderate advisories. Closed by pinning patched transitive versions — not the one-click "fix" the tooling suggests, which is actually a downgrade. Verified: the dependency audit now reports zero, and the app still builds and type-checks clean.
The secrets scanner flagged a token in a file. A human checked it: a placeholder inside a framework's boilerplate README, not a credential. We allowlisted it with the reasoning written down — so the scan stays green and the judgment is auditable.
Backend dependencies: zero known vulnerabilities. No live credentials in the code or anywhere in the git history. The baseline was healthy before we touched it.
The fix, measured
4
misconfigurations
(2 high, 2 low)
0
both images
scan clean
Verified by re-running the same scanner against the fixed Dockerfiles. The fix, the re-scan, and the write-up all live in the repository as a single reviewable change — found and closed in the same sitting.
What was already right
OTP login rate-limited to three attempts a minute, refresh tokens rotated and stored only as hashes — a database dump yields nothing usable.
A global validation layer strips unknown fields and enforces types on every request, so malformed or injected payloads never reach the logic.
Security headers on by default; cross-origin access restricted to an explicit allowlist rather than left open.
The app refuses to boot in production without its secrets configured — insecure defaults can't reach production by accident. And no raw SQL anywhere: the ORM parameterizes every query.
The honest part
This is a static, dependency, and secrets baseline plus a running-app scan — not a penetration test. A baseline scan and a pentest catch different things; if a project needs the latter for compliance or funding due-diligence, we say so and refer it to a specialist. That honesty is the point.
"Security isn't an audit we ran once — it's a pipeline the app lives in."
Every finding above is now closed — the container hardening, the dependency CVEs, and the triaged false positive — and the whole pipeline runs green on every commit. But the point isn't a one-time clean report: the same scanners keep running, so new advisories and hardening get caught and tracked as the app evolves. Load-testing and production monitoring are part of the full sprint; this case study is scoped to the security pipeline.
Your turn
The same pipeline, the same reports, the same honest triage — on a fully functioning app shipped in seven days. Book a free 30-minute scoping call and we'll tell you whether your idea fits.
Book a free scoping call