Web Application Security & OWASP Top 10 Defense

Web applications and APIs represent the primary attack surface for modern enterprises. Because web services must remain publicly accessible to legitimate users over ports 80 and 443, perimeter firewalls alone cannot distinguish between legitimate business traffic and malicious application-layer exploits.

The Open Worldwide Application Security Project (OWASP) publishes the authoritative OWASP Top 10, identifying the most critical web application security risks. In this guide, we analyze the architectural root causes of leading web vulnerabilities (SQL Injection, Cross-Site Scripting, and Server-Side Request Forgery) and implement production defenses.


1. Injection Vulnerabilities (SQL Injection)#

Injection occurs when untrusted user input is directly concatenated into a dynamic database interpreter query without contextual escaping or parameterization:

python
# VULNERABLE CODE (DO NOT USE IN PRODUCTION)
# If user inputs: ' OR 1=1 --
query = f"SELECT * FROM users WHERE username = '{user_input}'"

The database interpreter interprets ' OR 1=1 -- as SQL syntax rather than literal data, returning all user records in the table and bypassing authentication.

Production Defense: Parameterized Queries (Prepared Statements)#

Prepared statements separate the SQL code from user-supplied data. The SQL query structure is pre-compiled by the database engine into an execution plan. User input is transmitted separately as parameter values and treated strictly as literal data, making SQL injection mathematically impossible:

python
# SECURE DEFENSE: Using Parameterized Placeholders
import sqlite3

def authenticate_user(username: str, password_hash: str):
    conn = sqlite3.connect("enterprise.db")
    cursor = conn.cursor()
    # User input is bound as parameters (?), never concatenated
    query = "SELECT id, email, role FROM users WHERE username = ? AND password_hash = ?"
    cursor.execute(query, (username, password_hash))
    return cursor.fetchone()

2. Cross-Site Scripting (XSS)#

Cross-Site Scripting occurs when an application includes untrusted data in an HTTP response rendered by a victim's browser without adequate validation or encoding:

  • Stored XSS: Malicious script is permanently stored in a database (e.g., in a comment field) and served to every user viewing the page.
  • Reflected XSS: Malicious script is reflected off the web server in an immediate HTTP response (e.g., inside a search query error message).
  • DOM-based XSS: Vulnerability exists purely in client-side JavaScript executing untrusted data from location.search directly into sinks like innerHTML or document.write.

Impact of XSS#

Once malicious JavaScript executes in the victim's browser context, the attacker can:

  • Steal sensitive session authentication cookies (document.cookie).
  • Perform unauthorized actions on behalf of the user (account takeover).
  • Capture keystrokes (in-browser keylogger) or redirect users to malicious phishing portals.

Multi-Layer XSS Defenses:#

  1. Context-Aware Output Encoding: Encode HTML entities (<, >, ", ', &) before rendering dynamic data. Modern frameworks (React, Next.js, Angular) perform contextual encoding by default when using standard JSX expressions {data}.
  2. HttpOnly Cookies: Protect session cookies by setting the HttpOnly flag. When enabled, client-side JavaScript cannot read document.cookie, neutralizing session theft via XSS!
  3. Content Security Policy (CSP): An HTTP response header instructing the browser which domains can execute scripts:

```http

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; object-src 'none';

```


3. Server-Side Request Forgery (SSRF)#

Server-Side Request Forgery occurs when a web application fetches a remote resource (e.g., downloading an avatar image or importing a webhook URL) without validating the destination address supplied by the user.

An attacker supplies an internal loopback or cloud metadata IP address:

text
Target URL: http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role

Because the request originates from the trusted web server inside the private VPC, the AWS Instance Metadata Service (IMDS) responds with IAM credentials, allowing the attacker to compromise the entire cloud account!

Production SSRF Mitigations:#

  • Strict URL Allow-listing: Validate requested URLs against an explicit allow-list of approved domains and protocols (e.g., only HTTPS).
  • DNS Resolution & Private IP Blocking: Resolve the hostname via DNS and reject any IP address falling within RFC 1918 private subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) or link-local ranges (169.254.169.254, 127.0.0.1).
  • Enforce IMDSv2: In cloud environments, mandate IMDSv2, which requires a session token obtained via HTTP PUT request with custom headers that SSRF payloads cannot forge.

Checkpoint Questions & Practice Exercises#

Question 1: Why does setting the HttpOnly flag on session cookies fail to prevent Cross-Site Request Forgery (CSRF) or prevent an attacker from executing API requests via an active XSS exploit?

  • Answer: HttpOnly strictly prevents JavaScript from reading the cookie value. When an attacker exploits XSS or CSRF to trigger an HTTP request to the backend server, the browser automatically attaches the session cookie to the outbound request regardless of HttpOnly. To prevent CSRF, anti-CSRF tokens or SameSite=Strict cookie flags are required.

Question 2: Explain the mechanism of a Blind SQL Injection attack and how an adversary extracts database information without seeing query errors or outputs.

  • Answer: In Blind SQLi, the application reveals no error messages or query results. An adversary infers information using boolean logic (observing whether the page loads normally or differently based on conditions like AND SUBSTRING(password, 1, 1) = 'a') or time-based blind logic (forcing the database to sleep via pg_sleep(5) or WAITFOR DELAY and measuring HTTP response latency).

Video Walkthrough & Explanation

Video WalkthroughHD 1080p

Web Application Security & OWASP Top 10 Defense — Video Walkthrough

Try It Yourself • Live Code Editor

Modify the code below and run it live in your browser:

Try It Yourself • PYTHON Sandbox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Output Console (stdout)
14ms
Insecure Raw SQL : SELECT * FROM accounts WHERE username = '' OR '1'='1' Leaked Accounts : [(1, 'alice', 5000), (2, 'bob', 1200)] -------------------------------------------------- Secure SQL Executed : SELECT * FROM accounts WHERE username = ? Secure Results : [] (Safe: Attack payload treated as literal string)
Click “Run Code” to execute any modifications directly in your browser

Practice Check • Quick Quiz

Test Your Understanding

Why do parameterized prepared statements completely neutralize SQL injection vulnerabilities?

A
Because they automatically encrypt the entire SQL database using AES-256.
B
Because the SQL query grammar is pre-compiled into an Abstract Syntax Tree before user input is supplied; user input is treated strictly as literal data.
C
Because they block all single quote characters from being submitted over HTTP.
D
Because they require root administrator permissions to execute.