{"id":8901,"date":"2026-09-10T13:47:38","date_gmt":"2026-09-10T08:17:38","guid":{"rendered":"https:\/\/www.techuz.com\/blog\/?p=8901"},"modified":"2026-09-15T03:52:52","modified_gmt":"2026-09-14T22:22:52","slug":"web-application-security-checklist","status":"publish","type":"post","link":"https:\/\/www.techuz.com\/blog\/web-application-security-checklist\/","title":{"rendered":"The Web Application Security Checklist: 25 Controls to Verify Before Launch"},"content":{"rendered":"<div style=\"background:#F1F5F9;border-left:4px solid #475569;border-radius:8px;padding:20px 24px;margin-bottom:28px;\">\n<p style=\"margin:0 0 12px;\"><strong>Quick Answer:<\/strong> A web application is ready to launch when 25 controls across six layers (authentication, authorization, data, dependencies, infrastructure, and monitoring) have each been verified by someone, on purpose, recently. Not assumed. Verified.<\/p>\n<p style=\"margin:0;\">The priority order is not guesswork: broken access control holds the #1 spot in the <a href=\"https:\/\/owasp.org\/Top10\/2025\/A01_2025-Broken_Access_Control\/\" rel=\"nofollow noopener\" target=\"_blank\">OWASP Top 10:2025, where 100% of applications tested showed some form of it<\/a>, and <a href=\"https:\/\/www.ibm.com\/reports\/data-breach\" rel=\"nofollow noopener\" target=\"_blank\">IBM puts the global average cost of a data breach at $4.88 million<\/a>. Every control below includes what it protects against, how to verify it in about an hour, and the common way it&#8217;s done wrong, so a technical founder can turn &#8220;I think so&#8221; into &#8220;checked, on this date, by this person.&#8221;<\/p>\n<\/div>\n<p>The email that prompts this article arrives in every founder&#8217;s inbox eventually. An enterprise prospect is interested, the deal is real, and attached is a security questionnaire: 40 questions, sometimes 200. You read &#8220;Is customer data encrypted at rest?&#8221; and &#8220;Are access controls enforced server-side?&#8221; and you answer yes, because you believe so, because your developers are good people, and because no is not an answer that closes deals.<\/p>\n<p>Then, somewhere around question 30, the honest thought arrives: <em>I don&#8217;t actually know if these answers are true.<\/em><\/p>\n<p>This checklist exists for that moment. It is the 25 controls we verify as a <a href=\"https:\/\/www.techuz.com\/web-development\/\">custom web development company in the USA<\/a> market before we let anything we build face the internet, grouped into six layers, each with the attack it prevents, a verification you can run in about an hour, and the specific way teams get it wrong while believing they got it right.<\/p>\n<h2 id=\"questionnaires\">Why Security Questionnaires Expose More Than Penetration Tests<\/h2>\n<p>A penetration test is a snapshot: skilled people attack the application for a week and report what broke. It is valuable, and it answers a narrow question: what could this team exploit, this week. A questionnaire asks a more revealing one: <em>do you know your own security posture?<\/em> &#8220;Is data encrypted at rest?&#8221; has three possible states: yes, no, and the most dangerous one, &#8220;we assume so.&#8221; Questionnaires are embarrassing precisely because they expose the third state, and the third state is where breaches live.<\/p>\n<p>Security researcher Bruce Schneier compressed the whole discipline into seven words:<\/p>\n<blockquote style=\"border-left:4px solid #475569;margin:24px 0;padding:8px 24px;color:#374151;\">\n<p style=\"margin:0 0 8px;font-style:italic;\">&#8220;Security is a process, not a product.&#8221;<\/p>\n<p style=\"margin:0;font-size:15px;color:#6B7280;\">Bruce Schneier, The Process of Security (2000)<\/p>\n<\/blockquote>\n<p>The process, concretely, is verification with a name and a date attached. That is all this checklist asks: 25 controls, each moved from &#8220;assumed&#8221; to &#8220;checked.&#8221; Here is the map.<\/p>\n<figure style=\"margin:28px 0;text-align:center;\">\n<img decoding=\"async\" src=\"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-inpost-1-six-layers.png\" alt=\"25 security controls across six layers: authentication and sessions (5), authorization (4), data (5), dependencies (4), infrastructure (4), and monitoring and readiness (3)\" style=\"max-width:100%;height:auto;border-radius:8px;\" \/><br \/>\n<\/figure>\n<h2 id=\"authentication\">Layer 1: Authentication and Sessions (Controls 1-5)<\/h2>\n<p>Authentication is the front door, and attackers rarely pick the lock; they try keys stolen from somewhere else. These five controls assume credential-stuffing lists and phished passwords are already in play, because they are.<\/p>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>1. Modern password hashing<\/strong> (bcrypt, scrypt, or Argon2)<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">A stolen database becoming usable passwords<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Look at one stored hash: it should start with $2b$, $argon2, or similar<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">MD5\/SHA-1, or a homemade scheme from an old tutorial<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>2. MFA available, enforced for admins<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Account takeover with a phished or reused password<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Try to log into an admin account with password alone<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">MFA offered to users, admin panel exempt &#8220;for convenience&#8221;<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>3. Rate limiting and lockout on auth endpoints<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Credential stuffing and brute force<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Script 50 rapid login attempts against staging; count how many are processed<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The login form is limited, the API endpoint behind it isn&#8217;t<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>4. Session expiry and rotation<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Hijacked sessions living forever<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Change the password in one browser; confirm the session in a second browser dies<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Tokens that never expire and survive password changes<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>5. Secure cookie flags<\/strong> (HttpOnly, Secure, SameSite)<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Token theft via XSS; cross-site request forgery<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Open devtools, inspect the session cookie&#8217;s flags<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The session token in localStorage, readable by any injected script<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"authorization\">Layer 2: Authorization (Controls 6-9)<\/h2>\n<p>This layer deserves its own headline. In the <a href=\"https:\/\/owasp.org\/Top10\/2025\/A01_2025-Broken_Access_Control\/\" rel=\"nofollow noopener\" target=\"_blank\">OWASP Top 10:2025, broken access control holds the #1 position, with 100% of applications tested showing some form of it<\/a>, up from 94% in the 2021 edition. The most common critical flaw in web applications is not an exotic exploit. It is an authorization check that simply is not there: the UI hides the button, and the API behind it never asks who&#8217;s calling.<\/p>\n<figure style=\"margin:28px 0;text-align:center;\">\n<img decoding=\"async\" src=\"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-inpost-2-owasp-data.png\" alt=\"The case for verifying authorization first: broken access control is number one in the OWASP Top 10 2025, with 100% of tested applications showing some form of it, while IBM puts the average cost of a data breach at 4.88 million dollars\" style=\"max-width:100%;height:auto;border-radius:8px;\" \/><br \/>\n<\/figure>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>6. Server-side authorization on every endpoint<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Forced browsing to functions the UI hides<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">As a low-privilege user, call three admin API routes directly<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Authorization lives in the frontend; the API trusts whoever arrives<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>7. Object-level ownership checks<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">IDOR: reading someone else&#8217;s records by changing an ID<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Log in as user A, request user B&#8217;s invoice by ID<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Sequential IDs plus a lookup that never checks the owner<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>8. Server-side role checks for admin functions<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Vertical privilege escalation<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Edit your role claim client-side; see if the server honors it<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The role read from a client-modifiable token, unverified<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>9. Tenant isolation in every query<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Cross-tenant data leaks in multi-tenant apps<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">From tenant A, attempt to fetch tenant B&#8217;s data on staging<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">One query, somewhere, missing the tenant scope<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>If you verify only one layer before launch, verify this one. It is where a <a href=\"https:\/\/www.techuz.com\/saas-development-company\/\">SaaS development company<\/a> earns its keep on multi-tenant builds, because control 9 is a discipline applied to every query ever written, not a setting.<\/p>\n<h2 id=\"data\">Layer 3: Data (Controls 10-14)<\/h2>\n<p>Data controls decide the blast radius: whether an intrusion becomes an incident report or a regulatory event. <a href=\"https:\/\/www.ibm.com\/reports\/data-breach\" rel=\"nofollow noopener\" target=\"_blank\">IBM&#8217;s global average breach cost of $4.88 million<\/a> is mostly made of this layer&#8217;s failures.<\/p>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>10. TLS everywhere, with HSTS<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Interception and downgrade attacks<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Run an SSL Labs scan; try an http:\/\/ URL and confirm the redirect<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">TLS at the load balancer, plaintext between internal services<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>11. Encryption at rest, including backups<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Stolen disks, snapshots, and backup files<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Check the database and the backup storage settings, separately<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Production encrypted; the S3 bucket of backups, not<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>12. Secrets in a manager, not in code<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Leaked API keys and database credentials<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Run a secrets scanner (gitleaks, trufflehog) over the repo and its history<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The .env file that was committed once, three years ago, and lives in history forever<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>13. PII inventory, minimization, and log hygiene<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Oversized breach impact; GDPR and privacy exposure<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">List every PII field you store; grep the logs for emails and tokens<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Full request bodies, PII included, sitting in application logs<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>14. Backups that restore<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Ransomware and data loss becoming extinction events<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Restore last night&#8217;s backup to staging; time it<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Backups taken daily for years, restored never<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div style=\"background:#0E1B3D;border-radius:10px;padding:26px 28px;margin:32px 0;color:#FFFFFF;\">\n<p style=\"margin:0 0 10px;font-size:20px;font-weight:700;color:#FFFFFF;\">Staring down a security questionnaire right now?<\/p>\n<p style=\"margin:0 0 18px;color:#D7DEF0;\">Techuz runs pre-launch security reviews against this exact checklist: every control verified, evidence collected, and a report you can attach to the questionnaire instead of hoping.<\/p>\n<p><a href=\"https:\/\/www.techuz.com\/web-development\/\" style=\"display:inline-block;background:#475569;color:#FFFFFF;padding:12px 26px;border-radius:6px;text-decoration:none;font-weight:600;\">Request a security review<\/a>\n<\/p><\/div>\n<h2 id=\"dependencies\">Layer 4: Dependencies (Controls 15-18)<\/h2>\n<p>Your application is mostly other people&#8217;s code: framework, packages, and increasingly, AI-generated snippets. This is the layer most teams skip entirely, and OWASP has ranked vulnerable and outdated components as a top-ten risk in every recent edition.<\/p>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>15. Automated dependency scanning in CI<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Shipping packages with known CVEs<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Open the last five scanner alerts; check who closed them, and when<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Alerts enabled, assigned to nobody, 400 unread<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>16. Lockfiles and pinned versions<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Builds silently pulling different, compromised versions<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Confirm the lockfile is committed and CI installs from it<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Version ranges that resolve differently in prod than on laptops<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>17. Review of AI-generated and pasted code<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Insecure patterns entering at generation speed<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Sample five recent AI-assisted PRs; run SAST over auth and input paths<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Generated auth code trusted because it looked idiomatic<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>18. Least-privilege keys for third-party services<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">One compromised vendor unlocking everything<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">List every external API key and what it&#8217;s scoped to<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">A single god-key with full permissions, shared across services<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Control 17 is the 2026 addition to a classic list. AI assistants produce code that compiles, reads cleanly, and reproduces the average security of its training data; the risk mechanics are the ones we unpacked in <a href=\"https:\/\/www.techuz.com\/blog\/mvp-shipping-fast-technical-credibility\/\">why MVP speed is meaningless without technical credibility<\/a>. Generated code is a draft from a stranger, and it gets a stranger&#8217;s code review.<\/p>\n<h2 id=\"infrastructure\">Layer 5: Infrastructure (Controls 19-22)<\/h2>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>19. Security headers<\/strong> (CSP, X-Frame-Options, and peers)<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">XSS amplification and clickjacking<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Run the site through securityheaders.com; read the grade<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Whatever the framework shipped by default, unreviewed<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>20. Parameterized queries everywhere<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">SQL and query injection<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Grep for string-concatenated queries; run sqlmap against staging forms<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The ORM used everywhere except one legacy raw query<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>21. File upload restrictions<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Remote code execution via uploaded files<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Try uploading a script file with a doctored extension; check where files are stored<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Client-side extension checks; uploads served from the webroot<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>22. Environment separation<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Production data and credentials leaking through dev<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Check what data staging holds and who can reach it<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">A full production copy on every developer laptop<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"monitoring\">Layer 6: Monitoring and Incident Readiness (Controls 23-25)<\/h2>\n<p>The last layer accepts an uncomfortable premise: something will eventually get through. What separates a contained incident from a $4.88 million one is how fast you notice and how prepared the first hour is.<\/p>\n<table style=\"width:100%;border-collapse:collapse;margin:20px 0;\">\n<thead>\n<tr>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Control<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Protects against<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Verify in an hour<\/th>\n<th style=\"border:1px solid #D6DDE6;padding:10px 12px;text-align:left;background:#F1F5F9;\">Common failure<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>23. Centralized security logging<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Blind forensics; attackers erasing their tracks<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Fail five logins, then find them in the log platform<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Logs stored only on the server that just got compromised<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>24. Alerting a human actually receives<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Breaches discovered by customers or journalists<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Fire a test alert; confirm who was paged and how fast<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Beautiful dashboards that no one is watching at 2 a.m.<\/td>\n<\/tr>\n<tr>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\"><strong>25. A one-page incident response plan<\/strong><\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Chaos, delay, and legal missteps in the first hour<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">Run a 30-minute tabletop: &#8220;we think customer data is leaking, go&#8221;<\/td>\n<td style=\"border:1px solid #D6DDE6;padding:10px 12px;\">The plan exists in one senior engineer&#8217;s head, and they&#8217;re on holiday<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"sign-off\">The Pre-Launch Sign-Off Sheet<\/h2>\n<p>The checklist becomes a governance tool with one addition: a name and a date. Before launch, each layer gets an accountable owner who verifies its controls and signs. &#8220;Mostly verified&#8221; is a finding, not a pass; a control that fails verification is a ticket, not a footnote. Kept in the repo and re-run at every major release, this sheet is also the honest answer to the next security questionnaire: not &#8220;yes,&#8221; but &#8220;verified, on this date, by this person,&#8221; which is the answer enterprise buyers are actually probing for.<\/p>\n<figure style=\"margin:28px 0;text-align:center;\">\n<img decoding=\"async\" src=\"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-inpost-3-signoff-sheet.png\" alt=\"The pre-launch sign-off sheet: six layers with controls-verified counts out of 5, 4, 5, 4, 4 and 3, a signature line for the accountable owner and a date, totaling 25 of 25 before launch\" style=\"max-width:100%;height:auto;border-radius:8px;\" \/><br \/>\n<\/figure>\n<p>One honest caveat about scope: these 25 controls are the launch baseline for a typical web application, the floor that makes you a hard target rather than an easy one. Regulated industries add layers on top (HIPAA, PCI DSS, SOC 2 have their own regimes), and none of this replaces periodic penetration testing; it makes the pen test worth its fee, because the findings will be interesting instead of embarrassing. And the economics compound quietly: skipping these controls is the security version of the pattern we mapped in <a href=\"https:\/\/www.techuz.com\/blog\/hidden-cost-of-cheap-engineering-technical-debt\/\">the hidden APR of cheap code<\/a>, a discount at build time financed at breach-time interest rates.<\/p>\n<div style=\"background:#0E1B3D;border-radius:10px;padding:26px 28px;margin:32px 0;color:#FFFFFF;\">\n<p style=\"margin:0 0 10px;font-size:20px;font-weight:700;color:#FFFFFF;\">Launch with the sheet already signed<\/p>\n<p style=\"margin:0 0 18px;color:#D7DEF0;\">Techuz builds with these controls in the definition of done, not bolted on before the questionnaire arrives. That&#8217;s what secure <a href=\"https:\/\/www.techuz.com\/web-development\/\" style=\"color:#94A3B8;text-decoration:underline;\">custom web development<\/a> means in practice: evidence, not assurances.<\/p>\n<p><a href=\"https:\/\/www.techuz.com\/contact-us\/\" style=\"display:inline-block;background:#475569;color:#FFFFFF;padding:12px 26px;border-radius:6px;text-decoration:none;font-weight:600;\">Start a conversation<\/a>\n<\/p><\/div>\n<h2 id=\"faqs\">FAQs<\/h2>\n<h3>Is this checklist a replacement for a penetration test?<\/h3>\n<p>No, it&#8217;s the prerequisite. A pen test on an application that hasn&#8217;t verified these 25 controls produces a long list of known issues you paid to rediscover. Verify the baseline first, then let the pen test hunt for what a checklist can&#8217;t catch: logic flaws, chained exploits, and your specific blind spots.<\/p>\n<h3>Which security controls should we verify first?<\/h3>\n<p>Authorization (controls 6 through 9). Broken access control is ranked #1 in the OWASP Top 10:2025, with 100% of tested applications showing some form of it. It&#8217;s also among the cheapest to test: an afternoon of changing IDs and calling admin endpoints as a normal user reveals most of it.<\/p>\n<h3>How long does it take to verify all 25 controls?<\/h3>\n<p>Each control is designed to be verifiable in about an hour, so a focused week covers the list for a typical application. The first pass is the slow one; subsequent releases only re-verify what changed, plus a quarterly full pass.<\/p>\n<h3>Do these controls cover SaaS security requirements for enterprise deals?<\/h3>\n<p>They cover the technical majority of what questionnaires ask, especially with the sign-off sheet as evidence. Enterprise deals often add organizational requirements (SOC 2, policies, vendor management) that sit on top of this baseline rather than replacing it. Passing the technical layer is what makes the rest a paperwork exercise instead of an engineering scramble.<\/p>\n<h3>Is AI-generated code a real security risk or a hypothetical one?<\/h3>\n<p>Real, and mechanical: generated code reproduces the average patterns of its training data, including insecure ones, at a speed that outruns casual review. Control 17 treats it accordingly: the same review and static analysis as code from a stranger, because that is what it is. A <a href=\"https:\/\/www.techuz.com\/web-development\/\">web development services<\/a> partner using AI tooling should be able to show you that review step in their process.<\/p>\n<h2 id=\"sources\">Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/owasp.org\/Top10\/2025\/A01_2025-Broken_Access_Control\/\" rel=\"nofollow noopener\" target=\"_blank\">OWASP Top 10:2025, A01 Broken Access Control<\/a><\/li>\n<li><a href=\"https:\/\/owasp.org\/Top10\/2021\/A01_2021-Broken_Access_Control\/\" rel=\"nofollow noopener\" target=\"_blank\">OWASP Top 10:2021, A01 Broken Access Control (94% of tested applications)<\/a><\/li>\n<li><a href=\"https:\/\/www.ibm.com\/reports\/data-breach\" rel=\"nofollow noopener\" target=\"_blank\">IBM, Cost of a Data Breach Report 2024<\/a><\/li>\n<li><a href=\"https:\/\/www.schneier.com\/essays\/archives\/2000\/04\/the_process_of_secur.html\" rel=\"nofollow noopener\" target=\"_blank\">Bruce Schneier, The Process of Security (2000)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Quick Answer: A web application is ready to launch when 25 controls across six layers (authentication, authorization, data, dependencies, infrastructure, and monitoring) have each been verified by someone, on purpose, recently. Not assumed. Verified. The priority order is not guesswork: broken access control holds the #1 spot in the OWASP Top 10:2025, where 100% of &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.techuz.com\/blog\/web-application-security-checklist\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;The Web Application Security Checklist: 25 Controls to Verify Before Launch&#8221;<\/span><\/a><\/p>\n","protected":false},"author":18,"featured_media":8891,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[397,38,417],"better_featured_image":{"id":8891,"alt_text":"The Web Application Security Checklist: 25 Controls to Verify Before Launch","caption":"","description":"","media_type":"image","media_details":{"width":1600,"height":720,"file":"2026\/09\/Security-Checklist-Featured-Image.png","filesize":90305,"sizes":{"medium":{"file":"Security-Checklist-Featured-Image-300x135.png","width":300,"height":135,"mime-type":"image\/png","filesize":18014,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-300x135.png"},"large":{"file":"Security-Checklist-Featured-Image-1024x461.png","width":1024,"height":461,"mime-type":"image\/png","filesize":88544,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-1024x461.png"},"thumbnail":{"file":"Security-Checklist-Featured-Image-150x150.png","width":150,"height":150,"mime-type":"image\/png","filesize":8135,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-150x150.png"},"medium_large":{"file":"Security-Checklist-Featured-Image-768x346.png","width":768,"height":346,"mime-type":"image\/png","filesize":62744,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-768x346.png"},"1536x1536":{"file":"Security-Checklist-Featured-Image-1536x691.png","width":1536,"height":691,"mime-type":"image\/png","filesize":142651,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-1536x691.png"},"blog_list":{"file":"Security-Checklist-Featured-Image-460x207.png","width":460,"height":207,"mime-type":"image\/png","filesize":33175,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-460x207.png"},"alm-thumbnail":{"file":"Security-Checklist-Featured-Image-150x150.png","width":150,"height":150,"mime-type":"image\/png","filesize":8135,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-150x150.png"},"twentyseventeen-thumbnail-avatar":{"file":"Security-Checklist-Featured-Image-100x100.png","width":100,"height":100,"mime-type":"image\/png","filesize":4653,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image-100x100.png"}},"image_meta":{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","keywords":[]}},"post":null,"source_url":"https:\/\/www.techuz.com\/blog\/wp-content\/uploads\/2026\/09\/Security-Checklist-Featured-Image.png"},"_links":{"self":[{"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/posts\/8901"}],"collection":[{"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/comments?post=8901"}],"version-history":[{"count":2,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/posts\/8901\/revisions"}],"predecessor-version":[{"id":8903,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/posts\/8901\/revisions\/8903"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/media\/8891"}],"wp:attachment":[{"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/media?parent=8901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/categories?post=8901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techuz.com\/blog\/wp-json\/wp\/v2\/tags?post=8901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}