Prepare for Your First Penetration Test
14 May 2026Most first-time pentest reports are 80% findings you already knew about. Missing security headers, an outdated TLS cipher, a login form with no rate limit. You pay by the hour for the tester to write those up instead of hunting for the vulnerability that actually matters. Fix the obvious stuff first.
What testers always find
Give any competent tester a week against an unprepared app and they’ll hand you the same list every time: default credentials on an admin panel, verbose error messages leaking stack traces, a .git directory served publicly, and TLS 1.0 still enabled somewhere. None of that requires skill to find. It requires you not to have checked.
1. Patch everything
Run your dependency scanner before they do:
npm audit --production
docker scan yourimage:latest
Update the OS packages on every box in scope, not just the app server. A pentest that finds an unpatched Redis exposed on the internal network is a pentest that never gets to your actual code.
2. Kill default and shared credentials
Grep your codebase and infra configs for anything that looks like a leftover:
grep -riE "admin:admin|password.?=.?['\"]?(admin|changeme|test123)" -r .
Rotate any credential that’s been in a Slack message, a README, or a .env.example with a real value in it.
3. Close the ports you forgot about
nmap -sV -p- your-server-ip
Anything that isn’t 80, 443, and SSH from a restricted IP range should have a reason to be open. Postgres on 0.0.0.0:5432 is the single most common “critical” finding in small-company pentests.
4. Check your TLS config
testssl.sh --quiet yourdomain.com
Disable TLS 1.0/1.1, drop weak ciphers, and make sure HSTS is actually set — not just in your head.
5. Scan for secrets in git history
A secret that’s no longer in the current commit is still in the repo:
gitleaks detect --source . --verbose
Rotate anything it finds. Deleting the file doesn’t remove it from history; you need to rotate the credential, full stop.
6. Rate-limit auth endpoints
Login, password reset, and signup forms with no rate limiting are an automatic finding. Add it at the reverse proxy if you don’t want to touch app code — nginx’s limit_req or a Cloudflare rule both work.
What to hand the testers
Before the engagement starts, give them:
| Item | Why |
|---|---|
| Scope doc (domains, IP ranges, out-of-bounds systems) | Keeps them off your billing infra or vendor systems by accident |
| Test accounts at each role/tier | Saves hours of them trying to self-register and guess permissions |
| A contact for a “stop, this looks live” moment | So a false-positive DoS doesn’t take down production |
| Your existing threat model or architecture diagram, if you have one | Points them at what actually matters instead of the whole surface |
During the test
You’ll get alerts. WAF trips, failed login spikes, weird user agents. That’s expected — it’s the point. Don’t panic and start blocking IPs unless the tester’s own “stop” signal tells you to. If your monitoring stays silent through an active pentest, that’s a finding too, just one about your detection, not your app.
Do the free findings yourself. Save the budget for what a scanner can’t tell you — business logic flaws, auth bypass through a weird state transition, the thing only a human tester digging into your actual product will catch.