This checklist is designed for web developers, technical leads, and security-conscious engineering teams who want to eliminate the most common and critical vulnerabilities before code reaches production. Work through each step during development, code review, and pre-deployment testing to build applications that are secure by design.
Input Validation & Output Encoding
The vast majority of injection attacks — SQL injection, XSS, command injection — succeed because applications trust user-supplied data. Validate everything that enters your application and encode everything that leaves it.
- Validate all user input on the server side, never rely solely on client-side validation.
- Use an allowlist (whitelist) approach: define exactly what characters, formats, and lengths are acceptable for each input field.
- Reject or sanitise inputs that do not conform — do not attempt to silently fix malformed data.
- Use parameterised queries or prepared statements for every database interaction; never concatenate user input into SQL strings.
- Encode all output for the correct context: HTML-encode for HTML output, JavaScript-encode for script contexts, URL-encode for query parameters.
- Apply context-aware output encoding in your templating engine; turn off auto-escaping only when you fully control the content.
- Validate file names, MIME types, and content for any data that originates outside your system (e.g., third-party APIs, webhooks).
- Enforce strict type checking — cast inputs to the expected data type as early as possible.
Authentication & Session Management
Weak authentication is one of the leading causes of data breaches. Implement strong credential management and session controls to prevent account takeover and session hijacking.
- Enforce a strong password policy: minimum 12 characters, mix of character types, and check against known breached password lists (e.g., using the HaveIBeenPwned API).
- Store passwords using a modern, slow hashing algorithm: bcrypt, Argon2id, or scrypt with an appropriate cost factor — never MD5 or SHA-1.
- Implement Multi-Factor Authentication (MFA) — at minimum, offer TOTP-based MFA; require it for privileged accounts.
- Generate session tokens with a cryptographically secure random number generator (CSPRNG) and make them at least 128 bits long.
- Regenerate the session ID immediately after a successful login (prevent session fixation).
- Set session cookies with
HttpOnly,Secure, andSameSite=Strict(orLax) flags. - Implement absolute and idle session timeouts; log users out after a defined period of inactivity.
- Apply rate limiting and account lockout (or CAPTCHA) on login endpoints to prevent brute-force attacks.
- Ensure logout invalidates the session token on the server side, not just on the client.
- Use constant-time comparison functions when validating tokens, hashes, or secrets to prevent timing attacks.
Access Control (Authorisation)
Authentication proves who a user is; authorisation determines what they can do. Broken access control is consistently one of the top vulnerabilities in web applications — enforce it rigorously on every request.
- Apply the principle of least privilege: every user, service account, and process should have only the minimum permissions required.
- Perform authorisation checks on the server side for every sensitive action — never trust client-side role or permission values.
- Implement role-based access control (RBAC) or attribute-based access control (ABAC) using a centralised, auditable library or module.
- Deny access by default; explicitly grant permissions rather than explicitly denying them.
- Verify that users can only access their own resources (prevent Insecure Direct Object Reference — IDOR) by checking ownership on every data retrieval.
- Protect administrative endpoints and pages with separate, stricter access controls — do not rely on obscurity.
- Log every failed authorisation attempt with sufficient context (user ID, resource, timestamp) for forensic review.
- Review access control logic during every code review, especially when features are modified or new roles are added.
Cryptography & Data Protection
Sensitive data must be protected both at rest and in transit. Using weak or outdated cryptographic algorithms is as dangerous as using none at all.
- Enforce HTTPS (TLS 1.2 minimum, prefer TLS 1.3) across the entire application — Sensagraph checks your TLS configuration and certificate validity automatically.
- Disable deprecated protocols: SSL 2/3, TLS 1.0, TLS 1.1.
- Use strong, modern cipher suites; disable RC4, DES, 3DES, and export-grade ciphers.
- Use AES-256-GCM or ChaCha20-Poly1305 for symmetric encryption of sensitive data at rest.
- Never roll your own cryptography — use well-maintained, peer-reviewed libraries.
- Generate encryption keys with a CSPRNG and store them separately from the data they protect (e.g., in a secrets manager or hardware security module).
- Implement key rotation policies and document the process for emergency key revocation.
- Identify and classify sensitive data (PII, payment data, health data) and ensure it is encrypted wherever stored or transmitted.
- Avoid storing sensitive data you do not need — minimise your data footprint.
- Use HSTS (HTTP Strict Transport Security) with a long
max-ageand includeincludeSubDomainsandpreloaddirectives.
Error Handling & Logging
Poor error handling reveals your application's internals to attackers. Inadequate logging means you won't know an attack is happening until the damage is done.
- Display generic, user-friendly error messages to end users — never expose stack traces, database errors, or internal paths.
- Log detailed error information server-side where only authorised personnel can access it.
- Implement a global exception handler to catch unhandled errors and prevent accidental information disclosure.
- Log all security-relevant events: login attempts (success and failure), privilege escalation, password changes, access control failures, and data exports.
- Include contextual data in logs: timestamp (UTC), user ID, IP address, request path, and outcome — but never log passwords, tokens, or full credit card numbers.
- Protect log files from tampering: use append-only storage, ship logs to a centralised SIEM, and restrict write access.
- Set up real-time alerting on anomalous patterns (e.g., high failure rates, unusual access times, repeated authorisation failures).
- Retain logs for a period that meets your compliance requirements (typically 90 days minimum, often 1 year).
Dependency & Supply Chain Security
Modern web applications depend on dozens or hundreds of third-party packages. A vulnerability in any dependency is a vulnerability in your application.
- Maintain an accurate inventory (Software Bill of Materials — SBOM) of all direct and transitive dependencies.
- Use a dependency vulnerability scanner (e.g.,
npm audit,pip-audit,Dependabot,Snyk) and integrate it into your CI/CD pipeline. - Pin dependency versions in lock files (
package-lock.json,Pipfile.lock,composer.lock) and commit them to source control. - Review the security track record and maintenance activity of libraries before adopting them.
- Remove unused dependencies promptly — every unused package is unnecessary attack surface.
- Subscribe to security advisories for your key dependencies (GitHub Security Advisories, mailing lists, CVE feeds).
- Verify package integrity using checksums or signatures where the package registry supports it.
- Avoid running package install scripts (
postinstallhooks) from untrusted packages.
Security Headers & Transport Security
HTTP security headers are a fast, high-impact way to reduce your attack surface. Misconfigured or missing headers are a common finding in security assessments — Sensagraph checks all major security headers on every scan.
- Set
Content-Security-Policy (CSP)to restrict sources of scripts, styles, images, and other resources; use nonces or hashes instead of'unsafe-inline'. - Set
X-Content-Type-Options: nosniffto prevent MIME-type sniffing. - Set
X-Frame-Options: DENY(or use CSP'sframe-ancestorsdirective) to prevent clickjacking. - Set
Referrer-Policy: strict-origin-when-cross-origin(or stricter) to control referrer data leakage. - Set
Permissions-Policyto disable browser features your application does not use (camera, microphone, geolocation, etc.). - Enable HSTS with
max-ageof at least 31536000 (one year),includeSubDomains, and considerpreload. - Remove or obscure server version headers (
Server,X-Powered-By) to reduce fingerprinting exposure. - Configure CORS (Cross-Origin Resource Sharing) to allow only specific, trusted origins — never use a wildcard (
*) for authenticated endpoints.
API Security
APIs are often less visible than web UIs but equally — or more — exposed to attack. Every API endpoint must be treated as a potential attack vector.
- Authenticate every API request using a secure mechanism (OAuth 2.0 with short-lived tokens, API keys with strict scoping, or mutual TLS).
- Never embed API keys or secrets in client-side code, mobile app binaries, or public repositories.
- Validate and sanitise all API request parameters, headers, and bodies — apply the same input validation rules as for web forms.
- Implement rate limiting and throttling on all API endpoints to prevent abuse, scraping, and DoS.
- Return only the data a client needs — avoid over-fetching responses that expose unnecessary fields.
- Version your API and deprecate old versions securely; do not leave undocumented legacy endpoints running indefinitely.
- Use JSON Schema or equivalent to validate request and response payloads.
- Ensure all API endpoints are covered by your authorisation checks — pay special attention to bulk operations and batch endpoints.
- Implement object-level and field-level authorisation (prevent BOLA/IDOR in APIs).
File Upload & Storage Security
File upload functionality is a common target for attackers seeking to upload webshells, malware, or oversized payloads that crash your application.
- Validate file type using both MIME type detection from file content (magic bytes) and the file extension — do not rely on the
Content-Typeheader alone. - Maintain an allowlist of permitted file extensions and MIME types; reject everything else.
- Limit file size on the server side and return a clear error when the limit is exceeded.
- Rename uploaded files to a randomly generated name before storage to prevent path traversal and filename-based attacks.
- Store uploaded files outside the web root, in a location not directly accessible via URL.
- Serve user-uploaded files through a dedicated handler that sets appropriate headers (
Content-Disposition: attachment, correct MIME type) rather than serving them directly. - Scan uploaded files with antivirus or malware detection before processing or storing them.
- If images are accepted, re-encode them through a trusted image processing library to strip embedded malicious content.
Security Testing & Code Review
Security cannot be bolted on at the end of development — it must be embedded throughout your software development lifecycle (SDLC). Continuous testing and disciplined code review are your last lines of defence before deployment.
- Conduct security-focused code reviews for every pull request; use a security checklist as part of your review template.
- Integrate Static Application Security Testing (SAST) into your CI pipeline to catch vulnerabilities automatically as code is committed.
- Run Dynamic Application Security Testing (DAST) against staging environments; Sensagraph continuously scans your live application for exploitable vulnerabilities.
- Perform a manual penetration test at least annually or after significant architectural changes.
- Use threat modelling (e.g., STRIDE) at the design stage to identify and address security risks before writing any code.
- Establish and follow a responsible disclosure / bug bounty policy to receive reports from external researchers.
- Train developers in secure coding practices regularly — at least once per year, or when adopting a new technology stack.
- Track all identified vulnerabilities in your issue tracker with severity ratings and SLA-driven remediation deadlines.
- Include security acceptance criteria in every user story or ticket that touches authentication, data handling, or access control.