Build · · 2 min read
9 security checks before you launch a web app
The problems we find most often in apps that are about to go live. Each one takes minutes to check and is much cheaper to fix before launch than after.
These are the checks we run on our own builds before a client goes live. None of them replaces a penetration test. They catch the problems that should never reach one.
1. Every request checks who is asking
Sign in as one user and request another user's data by changing the ID in the URL or the request body. If you get it, the server is trusting the client. Check ownership on the server for every record, on every endpoint.
2. The admin area is not just hidden
Open the admin URLs while signed in as a normal user, and while signed out. A page that is missing from the menu is still reachable if the server does not check the role.
3. Secrets are not in the repository or the browser
Search the repository history for API keys and passwords. Then open the browser dev tools on the live build and search the JavaScript bundle for the same strings. Anything a browser downloads is public.
4. Login has a rate limit
Send 50 wrong passwords for one account in a minute. If none of them is slowed down or blocked, an attacker can guess passwords all day. Limit attempts per account and per IP address.
5. Password reset links expire and work once
Request a reset, wait an hour and use the link. Then use it a second time. Both should fail.
6. User input is escaped on output
Put <script>alert(1)</script> in every text field that is shown back to a user: names, comments, ticket subjects. If an alert box appears anywhere, you have stored XSS.
7. Security headers are set
Check the response headers of your home page. At a minimum:
Strict-Transport-Security: max-age=63072000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Add a Content-Security-Policy once you know which scripts your app loads.
8. Errors do not explain themselves to strangers
Trigger an error in production. The user should see a short message. Stack traces, SQL and file paths belong in your logs.
9. Backups exist and have been restored once
A backup that has never been restored is a guess. Restore one to a test environment before launch and time how long it takes.
After the checklist
If all 9 pass, you have closed the easy doors. A penetration test is how you find out about the ones that are not on a list.
More notes
Want this checked on your own product? Send us the brief.