Web application security
By the end of this module you will be able to:
- Apply all ten OWASP Top 10:2025 categories to a web application design
- Write a parameterised query that eliminates SQL injection risk
- Distinguish stored, reflected, and DOM-based XSS and select the correct mitigation
- Configure HTTP security response headers to reduce client-side attack surface

MOVEit Transfer CVE-2023-34362, May 2023
MOVEit Transfer and the Cl0p SQL injection wave
In May 2023, security researchers identified a critical SQL injection vulnerability in MOVEit Transfer, a managed file transfer application widely used by payroll processors, healthcare organisations, and government agencies. Within days, the Cl0p ransomware group had exploited it against more than 2,000 organisations worldwide.
In the United Kingdom, the breach reached Zellis, a payroll provider whose MOVEit installation was compromised, exposing payroll data for employees of the BBC, British Airways, Boots, and the NHS.
The vulnerability, CVE-2023-34362, was a SQL injection flaw: the application constructed SQL queries by concatenating user-controlled HTTP POST parameters. Progress Software released a patch on 31 May 2023 but exploitation had already begun on 27 May. Organisations with a software inventory and patch management programme would have applied the fix within hours of release rather than days.
OWASP Top 10:2025 overview
The OWASP Top 10 is updated approximately every three to four years based on analysis of real vulnerability data from hundreds of organisations. The 2025 edition, released in November 2025, retains Broken Access Control at A01 and elevates Software Supply Chain Failures to A03 - reflecting the SolarWinds, MOVEit, and xz-utils incidents. Injection dropped from A03 to A05 as parameterised queries and ORMs became more widely adopted. Two entirely new categories were added. The ten categories are:
- A01:2025 Broken Access Control - privilege abuse, BOLA, missing deny-by-default
- A02:2025 Security Misconfiguration - default credentials, verbose errors, cloud misconfiguration (up from A05:2021)
- A03:2025 Software Supply Chain Failures - compromised dependencies, unsigned updates, insecure CI/CD (new name, elevated from A08:2021)
- A04:2025 Cryptographic Failures - weak encryption, data exposure (moved from A02:2021)
- A05:2025 Injection - SQL, LDAP, command injection (dropped from A03:2021)
- A06:2025 Insecure Design - missing threat modelling, insecure architecture
- A07:2025 Authentication Failures - weak passwords, missing MFA (renamed from "Identification and Authentication Failures")
- A08:2025 Software or Data Integrity Failures - unsigned updates, insecure deserialization
- A09:2025 Security Logging and Alerting Failures - missing audit trails (renamed: "Monitoring" → "Alerting")
- A10:2025 Mishandling of Exceptional Conditions - error handling failures, uncaught exceptions (entirely new)
Note: SSRF, which was A10:2021, is now addressed under A02 (Security Misconfiguration) and A06 (Insecure Design) in the 2025 edition.
With an understanding of owasp top 10:2025 overview in place, the discussion can now turn to a01: broken access control, which builds directly on these foundations.
A01: Broken Access Control
Broken Access Control covers any scenario where a user can act outside their intended permissions, including vertical escalation (accessing admin functions) and horizontal escalation (accessing another user's data). OWASP reports 94% of tested applications had some form of broken access control.
The most reliable mitigation pattern is deny-by-default: all access is denied unless a positive authorisation decision exists for the combination of principal, resource, and action. Access control must be enforced server-side on every request. Client-side controls such as hidden fields, disabled buttons, and JavaScript checks are trivially bypassed.
With an understanding of a01: broken access control in place, the discussion can now turn to a04: cryptographic failures and a05: injection, which builds directly on these foundations.
A04: Cryptographic Failures and A05: Injection
A04:2025 Cryptographic Failures (formerly A02:2021 "Sensitive Data Exposure") covers: data transmitted in cleartext over HTTP, passwords hashed with MD5 or SHA-1 (both unsuitable due to speed; use bcrypt, Argon2, or PBKDF2), symmetric encryption using ECB mode (reveals plaintext patterns), and hard-coded cryptographic keys in source code. In June 2021, the RockYou2021 compilation of approximately 8.4 billion credential pairs revealed how widespread unsalted MD5 password storage was: MD5 can be computed at billions of hashes per second on consumer GPU hardware.
A05:2025 Injection occurs when untrusted data is sent to an interpreter as part of a command or query. The vulnerable pattern: concatenating user input into a SQL string. The correct pattern: a parameterised query that binds user input as data. If the input admin' -- is supplied to a concatenated query, it becomes a SQL comment that removes the password check. In a parameterised query, the same input is treated as a literal string and returns no results. LDAP injection, command injection, and template injection follow the same pattern: parameterise or use a safe API that separates code from data.
With an understanding of a04: cryptographic failures and a05: injection in place, the discussion can now turn to xss (cross-site scripting), which builds directly on these foundations.
XSS (Cross-Site Scripting)
XSS attacks inject malicious scripts into web pages viewed by other users. Three variants exist:
- Stored XSS: malicious script is persisted in the server's data store and served to all users who view the affected content. Highest impact because it affects every visitor without requiring a crafted link.
- Reflected XSS: malicious script is embedded in a URL parameter and reflected in the server's response. Requires the victim to click a crafted link. Search result pages that echo back the query term without escaping are a common vector.
- DOM-based XSS: the attack occurs entirely in the browser. Client-side JavaScript reads from a source (such as location.hash) and writes to a sink (such as innerHTML) without sanitisation. DOM-based XSS bypasses server-side encoding mitigations entirely.
Mitigation strategy: (1) output encoding using context-aware libraries such as OWASP Java Encoder or DOMPurify; (2) Content Security Policy header restricting script execution to approved sources; (3) HttpOnly cookies preventing JavaScript from reading session tokens even if a script executes.
With an understanding of xss (cross-site scripting) in place, the discussion can now turn to ssrf and security response headers, which builds directly on these foundations.
“A denial of access control vulnerability allows an attacker to gain unauthorised access to a resource or function. This is typically manifested as: accessing another user's account, changing another user's data, changing access rights, and bypassing access control checks.”
OWASP Top 10:2025, A01: Broken Access Control - A01:2021 – Broken Access Control
“Web application security requires a defence-in-depth approach. Input validation, output encoding, parameterised queries, and proper access controls must be implemented at every layer of the application, not applied selectively to high-risk endpoints.”
OWASP Application Security Verification Standard (ASVS) 4.0.3, Section 5: Validation, Sanitization and Encoding Requirements - Level 2 Requirements
SSRF and security response headers
Server-Side Request Forgery (SSRF) causes the server to make HTTP requests to an arbitrary destination, typically an internal network address or cloud metadata service, that the attacker cannot reach directly. In cloud environments, AWS, Azure, and GCP all expose an Instance Metadata Service at 169.254.169.254. A successful SSRF against an EC2 instance can retrieve the IAM role credentials attached to that instance.
In July 2019, Paige Thompson exploited SSRF via a misconfigured AWS WAF protecting a Capital One EC2 instance. The server-side request reached the IMDS endpoint and retrieved IAM role credentials, enabling download of over 106 million customer records from S3 buckets. Capital One was fined $80 million by the OCC in 2020. Mitigations: validate and allowlist outbound request targets; block requests to private IP ranges (RFC 1918) and link-local addresses (169.254.0.0/16); use AWS IMDSv2 which requires a PUT request before metadata can be read.
Security response headers that every application must include: Content-Security-Policy (restricts script origins, mitigates XSS), Strict-Transport-Security (forces HTTPS, prevents SSL stripping), X-Frame-Options: DENY (blocks clickjacking), X-Content-Type-Options: nosniff (prevents MIME-type attacks), Referrer-Policy: strict-origin, and Permissions-Policy (restricts browser API access). These headers must be applied to every origin, not just login pages.
Common misconception
“Security response headers only need to be added to the login page.”
Security headers must be applied to every origin your application serves, including API endpoints, subdomains, CDN edges, documentation portals, and error pages. An XSS or clickjacking attack on a status page or documentation subdomain can be used to steal credentials or pivot to authenticated areas. Automated header audit tools such as Mozilla Observatory should scan all configured origins during CI/CD pipeline runs.
Common misconception
“HTTPS (TLS) protects web applications from injection attacks and XSS.”
TLS protects data in transit from eavesdropping and tampering between the client and server. It has no effect on injection vulnerabilities (SQL injection, command injection) or XSS, which are server-side processing failures that occur after the TLS connection terminates. An application that uses HTTPS and also concatenates user input directly into SQL queries is simultaneously encrypted and trivially SQL-injectable. Input validation, parameterised queries, output encoding, and Content Security Policy are the controls relevant to injection and XSS, not TLS.
A web application reflects the search term in the page title without escaping it. An attacker crafts a link containing a script tag that reads document.cookie and posts it externally. The response has no CSP header. Which XSS type is this, and which mitigation would have prevented cookie theft even without CSP?
A developer finds a PHP application that concatenates a raw URL parameter into a SQL string. A tester submits the ID as '1 UNION SELECT username, password, 3, 4 FROM users--'. What has occurred and what is the correct fix?
A penetration tester identifies a reflected XSS vulnerability on a financial services website: the search parameter is included in the response without HTML encoding, allowing arbitrary JavaScript execution in the victim's browser. The application uses HttpOnly cookies for session tokens. The security team argues this is low severity because HttpOnly prevents cookie theft. Evaluate this assessment.
A developer adds a Content-Security-Policy header with the directive default-src 'self'. A third-party analytics script loaded from https://analytics.example.com stops working. What is the most appropriate fix?
Key takeaways
- OWASP Top 10:2025 retains Broken Access Control at A01 and elevates Software Supply Chain Failures to A03. Enforce deny-by-default server-side authorisation on every request, never client-side.
- SQL injection is prevented by parameterised queries or prepared statements. String concatenation of user input into SQL is never acceptable regardless of prior input validation.
- XSS has three forms: stored (highest impact), reflected (requires crafted link), and DOM-based (bypasses server-side encoding). Output encoding, CSP, and HttpOnly cookies work together as complementary controls.
- SSRF allows attackers to reach internal services and cloud metadata APIs via a vulnerable server. Allowlist outbound request targets and use AWS IMDSv2 on cloud instances.
- Security response headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options) must be applied to every origin and subdomain, not just login pages.
You can now identify and remediate the OWASP Top 10:2025 web vulnerabilities. Modern applications rarely stand alone - they expose and consume APIs. What happens when APIs lack authentication, authorisation, or rate limiting? Module 13 covers API and service security using the OWASP API Security Top 10.
Standards and sources cited in this module
OWASP Top 10:2025 (November 2025)
Primary vulnerability classification reference covering A01:2025 through A10:2025. Replaces the 2021 edition.
Verification requirements for validation, sanitisation, and encoding controls.
NIST SP 800-95: Guide to Secure Web Services
Web application security architecture guidance from NIST.
Content Security Policy directive reference and nonce-based CSP configuration guidance.
MOVEit Transfer SQL injection vulnerability: the case study for this module.

