Penetration Testing
Have a skilled human attack the application like a real adversary, finding the chains automated tools miss.
Why
Automated scanners (SAST, DAST) find individual vulnerabilities — a SQL injection here, a missing header there. A human pen tester finds the chains: the IDOR that leaks a session token, which enables an account takeover, which gives admin access to a billing endpoint that refunds to an attacker's card. These multi-step exploit chains are what real attackers use, and no automated tool can synthesize them because they require understanding the application's business logic, not just its technical patterns. A pen test is the most realistic validation of your security posture, and the report is concrete evidence for compliance (SOC 2, PCI-DSS) and for prioritizing fixes. It is expensive, so it is done periodically, not continuously.
When
Before major launches, before compliance audits (SOC 2, PCI-DSS), and at least annually for internet-facing applications. Also after any major architecture change. A re-test after fixes confirms the vulnerabilities are actually closed.
How
1. Scope the engagement precisely - List the in-scope URLs, features, and user roles - Define the rules of engagement: black-box (no source), gray-box (some info), white-box (full source) - Provide a test environment with realistic (anonymized) data, not production 2. Choose the tester - External firm (independent, broad experience, expensive) for compliance-grade reports - Internal red team (cheaper, more context, but may miss novel techniques) for ongoing validation - Bug bounty (HackerOne, Bugcrowd) for continuous, crowd-sourced testing of internet-facing apps 3. During the engagement (1-2 weeks) - The tester probes the app, chains findings, and attempts to reach a defined goal (admin access, data exfil) - Daily check-ins: discuss findings, clarify scope, avoid duplicate work - The tester may use any tool (Burp, custom scripts, social engineering if in scope) 4. Receive the report and triage - Each finding: description, reproduction steps, severity, business impact, remediation - Triage by risk = severity × exploitability × business impact - Fix criticals within 24-48h, highs within a week, mediums within a sprint 5. Re-test after fixes and maintain the report - Have the tester re-verify each fix — a "fix" that does not actually close the vuln is common - Keep the report as evidence for audits; track findings to closure in a tracker
Example
# Pen test report excerpt (simplified)
Finding P-03: Account takeover via IDOR + JWT reuse
Severity: Critical
Steps to reproduce:
1. As user A, note your JWT: eyJhbGc...
2. GET /api/users/123/sessions — returns A's sessions (A is user 123)
3. As user B (different account), send the same request with B's JWT
but change the URL to /api/users/123/sessions
4. Server returns user A's active sessions (IDOR — no ownership check)
5. Take A's session cookie from the response, set it in B's browser
6. B is now logged in as A — full account takeover
Business impact: Any user can take over any other user's account,
access their payment methods, and make purchases.
Remediation: Add ownership check to /api/users/:id/sessions —
verify req.user.id === Number(req.params.id) before returning sessions.
Status: Fixed in v2.3.1, re-tested by tester on 2024-04-15 — confirmed closed.
# This chain (IDOR → session theft → takeover) would not be found by SAST or DAST
# alone — it requires understanding the business logic of session management.Common Problems
- ⚠Scoping the pen test too narrowly (only the login page) to save cost — the tester finds nothing because the sensitive endpoints are out of scope, and the report gives false confidence that the app is secure.
- ⚠Treating the pen test as a one-time compliance checkbox — the report is filed, the criticals are fixed, but the mediums are never addressed, and the same vulnerabilities reappear in the next test because the root cause was not fixed.
- ⚠Not providing the tester with a realistic test environment — they test against an empty database and miss vulnerabilities that only appear with real data volumes (a pagination bug, a search injection).
- ⚠Skipping the re-test to save cost — a "fix" that does not actually close the vulnerability is common (the dev patched one entry point but missed three others), and only a re-test confirms the fix is complete.
Best Practices
- ✓Scope the pen test to cover all user roles and the highest-risk features (auth, payment, data access) — a narrowly-scoped test that finds nothing is a waste of money and a false signal.
- ✓Provide a dedicated test environment with realistic, anonymized production data so the tester can find vulnerabilities that depend on data shape (pagination, search, bulk operations).
- ✓Triage findings by risk (severity × exploitability × business impact), not just severity — a medium-severity IDOR on a payment endpoint is higher risk than a high-severity XSS on a marketing page.
- ✓Always re-test after fixes — pay for a re-test cycle where the tester verifies each fix, because incomplete fixes (patching one of several entry points) are the most common reason vulnerabilities recur.