The website security checklist we run before every launch
The specific checks that catch the majority of real-world website compromises — and why most of them have nothing to do with clever attacks.
Most websites are not compromised by novel techniques. They are compromised through an outdated dependency, an administrative interface left exposed, a file upload that never validated what it received, or credentials that were reused somewhere else. The unglamorous checks catch the majority of real incidents, which is why we run them the same way every time.
This is the checklist we work through before a site goes live. It is not exhaustive, and passing it does not make a site secure — nothing does. It closes the doors that are most often found open.
Dependencies and the supply chain
Every framework, plugin and package is code you did not write running with your application's privileges. Known vulnerabilities in outdated components are consistently among the most common causes of website compromise, largely because exploitation is automated: a scanner finds the version, a script does the rest.
- Audit every dependency for known advisories before launch, not after
- Remove packages that are no longer used — unused code is still attack surface
- Check that plugins are actively maintained; an abandoned plugin will not get a patch
- Pin versions so a deployment cannot silently pull in something new
- Set up automated advisory alerts so you learn about issues without checking manually
Authentication and session handling
Authentication is where the highest-value failures live. It is worth testing deliberately rather than assuming the framework handled it.
- Enforce a genuine password policy and check credentials against known-breached lists
- Rate-limit and lock out after repeated failed attempts
- Ensure password reset tokens are single-use, time-limited and unguessable
- Regenerate the session identifier on login and privilege change
- Set Secure, HttpOnly and SameSite on session cookies
- Offer multi-factor authentication for administrative accounts
Authorization
Authentication asks who you are. Authorization asks what you are allowed to touch — and it is the more commonly broken of the two. Broken access control has sat at the top of the OWASP Top 10 in recent revisions, and it rarely shows up in normal use because ordinary users never try.
The test that finds most of these: log in as a low-privilege user, then request a resource belonging to a different account by changing an identifier in the URL or request body. If it returns data, you have an object-level authorization problem.
- Check authorization on the server for every request, not just in the interface
- Verify object ownership, not merely that the user is logged in
- Deny by default and grant explicitly
- Test each role against endpoints intended for other roles
Input handling and file uploads
Anything a user sends is untrusted, including values your own interface produced. File uploads deserve particular attention because they combine untrusted content with the filesystem.
- Validate on the server against an allowlist; client-side validation is a convenience, not a control
- Use parameterised queries everywhere — string concatenation into SQL is still the classic mistake
- Encode output for the context it lands in to prevent cross-site scripting
- Verify uploaded file types by content rather than by extension
- Store uploads outside the web root, or serve them from a domain that cannot execute code
- Cap file sizes and upload rates
Configuration and exposed surfaces
A large share of findings in a typical assessment are configuration issues rather than code defects — things that were fine in development and were never changed for production.
- Turn off debug modes and verbose error pages in production
- Remove default accounts and sample content
- Ensure .git directories, backups, environment files and database dumps are not web-accessible
- Restrict administrative interfaces by network or additional authentication where practical
- Set security headers: Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy
- Confirm TLS is correctly configured and HTTP redirects to HTTPS
Logging, backups and recovery
The questions after an incident are always the same: when did this start, what did they reach, and can we get back to a known-good state? You can only answer them if you prepared beforehand.
- Log authentication events, privilege changes and administrative actions
- Keep logs somewhere an attacker on the web server cannot simply delete
- Take scheduled backups and store at least one copy offsite
- Actually perform a test restore — an untested backup is a hope, not a control
- Write down who to contact and what to do first, before you need it
What this checklist does not do
It does not cover business logic flaws, which are specific to your application and generally need a human to find. It does not address the infrastructure the site runs on beyond basic configuration. And it is a point-in-time exercise: a site that passes today will drift as dependencies age and features are added.
Treat it as the baseline you clear before launch, then keep clearing it on a schedule. If you want a deeper look at a specific application, that is what a vulnerability assessment or penetration test is for.
Written by
RegenByte
Articles are written by the RegenByte team from work on client projects. We publish what we have actually done rather than summarising other people’s posts.