Web Security Basics: OWASP Top 10 for Developers (2026)
Web Security in 2026: The Stakes Are Higher Than Ever
Web application security vulnerabilities have real consequences: user data exposure, financial loss, regulatory penalties under GDPR and CCPA, and reputational damage that can end a startup. The OWASP Top 10 — the Open Web Application Security Project's list of the most critical web application security risks — provides a framework for understanding and addressing the most impactful vulnerability categories. Understanding these vulnerabilities and their mitigations is a baseline competency for any developer shipping to production in 2026.
Injection: SQL, NoSQL, Command
Injection attacks occur when untrusted data is sent to an interpreter as part of a command or query. SQL injection remains one of the most common and devastating vulnerabilities despite being fully preventable. The fix: never concatenate user input into SQL queries. Use parameterized queries or ORM methods that handle escaping. Django's ORM, SQLAlchemy, and all major ORMs are safe by default — raw SQL constructed with string formatting is not. The same principle applies to LDAP queries, OS commands, and XML parsers.
XSS: Cross-Site Scripting
XSS attacks inject malicious scripts into web pages viewed by other users. Stored XSS saves the payload in the database; reflected XSS returns the payload in the immediate response; DOM XSS manipulates client-side code. React and Vue escape content by default — using dangerouslySetInnerHTML in React or v-html in Vue bypasses escaping and requires explicit sanitization with DOMPurify. CSP (Content Security Policy) headers provide a defense-in-depth layer by restricting which scripts can execute on the page.
Broken Authentication
Broken authentication encompasses weak passwords, missing account lockout after failed attempts, exposed session tokens in URLs, and missing secure/httpOnly flags on session cookies. Mitigations: use established authentication libraries rather than rolling custom auth, enforce strong password requirements and support passkeys/WebAuthn, implement rate limiting on authentication endpoints (5 attempts before lockout), store session tokens in httpOnly SameSite=Strict cookies not localStorage, and rotate session tokens after privilege escalation.
IDOR and Access Control
Insecure Direct Object Reference (IDOR) allows attackers to access other users' data by manipulating identifiers in requests — changing /api/orders/123 to /api/orders/124 to access another user's order. Fix: validate that the authenticated user has permission to access each specific resource, not just that they're authenticated. Never rely on obscurity (using non-sequential UUIDs instead of integers) as the sole protection — implement explicit authorization checks. Django's object-level permissions or custom permission classes in DRF handle this cleanly. Download our security-hardened Django API template at proofmatcher.com.
Security Misconfiguration
Many breaches come from settings rather than code. Common examples include debug mode left on in production, default admin passwords, directory listings, verbose error pages that reveal stack traces, and cloud storage buckets open to the public. Turn off debug output in production, return generic error messages to users while logging details privately, remove sample files and unused endpoints, and review cloud permissions regularly. Security headers are part of configuration too: a Content Security Policy limits which scripts can run and greatly reduces the impact of XSS, HTTP Strict Transport Security forces HTTPS, and X-Content-Type-Options: nosniff stops browsers from guessing file types.
Vulnerable and Outdated Components
Modern applications depend on hundreds of open-source packages, and a vulnerability in any of them can become yours. Run npm audit, pip-audit, or your ecosystem's equivalent in CI, enable automated dependency updates with Dependabot or Renovate, and remove packages you no longer use. Keep your runtime, framework, database, and server operating system patched as well. A small, regular update habit is far safer and easier than a large upgrade forced by an emergency.
Cryptographic Failures
Sensitive data must be protected in transit and at rest. Serve everything over HTTPS, including internal admin panels and APIs. Store passwords only as slow, salted hashes using Argon2id or bcrypt, never with fast hashes such as MD5 or SHA-256 alone, and never in reversible encryption. Encrypt sensitive fields such as national ID numbers or tokens at rest, keep encryption keys outside the database, and generate tokens and secrets with a cryptographically secure random generator rather than Math.random().
Cross-Site Request Forgery and Cookies
If your application uses cookie-based sessions, a malicious site can try to make the victim's browser send authenticated requests. Protect state-changing requests with CSRF tokens, which most frameworks such as Django provide built in, and set session cookies with SameSite=Lax or Strict, HttpOnly so JavaScript cannot read them, and Secure so they are only sent over HTTPS. Never perform state changes with GET requests.
Server-Side Request Forgery
SSRF happens when your server fetches a URL supplied by a user, such as for link previews, image imports, or webhooks, and an attacker points it at internal addresses. The server can then reach internal admin services or the cloud metadata endpoint that exposes credentials. Validate and allow-list destination hosts, resolve the address and block private and link-local ranges, disable redirects or re-validate each hop, and run such fetches from an isolated network where possible.
Software Supply Chain and Integrity
Attackers increasingly target the build pipeline itself. Commit lock files so installs are reproducible, review new dependencies before adding them, and watch for typo-squatted package names. Protect CI/CD secrets, pin third-party build actions to specific versions, and require code review before changes reach the main branch. Never load scripts from third-party domains you do not trust, and use Subresource Integrity hashes for scripts served from CDNs.
Logging, Monitoring, and Response
Many breaches go unnoticed for months because nobody was watching. Log authentication events, access-control failures, input validation failures, and administrative actions, and send the logs to a system where they are kept safe from tampering and can raise alerts. Set up alerts for unusual patterns such as many failed logins or sudden spikes in data exports. Finally, prepare a simple incident plan: who investigates, how to rotate keys and passwords quickly, how to restore from backups, and how to notify affected users when required by law.
Security Testing in Your Workflow
Security should be checked continuously, not once before launch. Static analysis tools scan source code for dangerous patterns such as SQL built from strings or unsafe HTML rendering. Dependency scanners flag packages with known vulnerabilities. Secret scanners, including GitHub's built-in secret scanning, catch API keys accidentally committed to a repository. Dynamic scanners such as OWASP ZAP test the running application from the outside, the way an attacker would. Run the fast checks on every pull request and the slower scans on a schedule, and fix high-severity findings before merging.
A Pre-Launch Security Checklist
- All traffic uses HTTPS, with HSTS enabled.
- Every endpoint checks authentication and verifies the user may access the specific record requested.
- Passwords are hashed with Argon2id or bcrypt, and login is rate limited.
- User input is validated on the server and all database access uses parameterised queries or an ORM.
- Output is escaped by the framework, and a Content Security Policy is in place.
- Cookies are
HttpOnly,Secure, andSameSite, and CSRF protection is enabled for cookie-based sessions. - Debug mode is off, error messages are generic, and admin panels are not publicly guessable.
- Dependencies are up to date, backups are automated, and restoring them has been tested.
Security is never finished. Review this checklist whenever you add a major feature, revisit the OWASP Top 10 when a new edition is published, and schedule an independent penetration test before handling payments or sensitive personal data at scale.