![]() |
| Ethical Hacking |
🛡️ Ethical Hacking — Day 18
Cross-Site Scripting (XSS) Fundamentals
⚠️ LEARNING PURPOSE ONLY: This tutorial and all practical exercises are strictly for educational and defensive cybersecurity learning. Perform the practical work only in your local OWASP Juice Shop lab, applications you own, or systems for which you have explicit authorization. Never test XSS on public websites without permission.
Welcome to Day 18.
Yesterday we studied SQL Injection, where malicious input can affect database queries.
Today we're moving to the browser side:
💻 XSS — Cross-Site Scripting
The basic idea is:
Attacker-controlled input
↓
Web application
↓
HTML / JavaScript context
↓
Browser interprets itXSS happens when untrusted data is included in a web page in a way that allows unintended script execution in a user's browser.
🎯 Day 18 Learning Objectives
Today you'll learn:
What XSS is
Why XSS happens
Reflected XSS
Stored XSS
DOM-based XSS
HTML context
JavaScript context
Input vs output
Browser rendering
Burp Suite XSS testing methodology
Safe XSS testing in Juice Shop
Output encoding
HTML escaping
Content Security Policy
Secure coding
Linux practical commands
Windows PowerShell practical commands
macOS practical commands
1. What Is XSS?
XSS stands for:
Cross-Site Scripting
The name can be confusing.
It doesn't mean:
Cross-site communicationInstead, it refers to a situation where an attacker-controlled value becomes executable browser content.
2. Simple XSS Architecture
User Input
↓
Web Application
↓
HTML Response
↓
Browser
↓
Unexpected JavaScript ExecutionThe fundamental security mistake is:
UNTRUSTED DATA
↓
TRUSTED HTML/JS CONTEXT3. Normal Web Page
Imagine a page contains:
<h1>Welcome, Rohit</h1>The browser interprets:
<h1>as HTML.
The text:
Rohitis supposed to be data.
A secure application keeps those concepts separate.
4. The Dangerous Situation
Imagine the application receives:
name = user-controlled inputand generates:
<h1>Welcome, USER_INPUT</h1>If the application doesn't safely encode the input, special markup could potentially become part of the page structure rather than remaining ordinary text.
That's the core XSS problem.
5. XSS vs SQL Injection
Compare them.
SQL Injection
User Input
↓
SQL Query
↓
DatabaseXSS
User Input
↓
HTML/JavaScript
↓
BrowserSo:
SQLi → Database
XSS → Browser6. Three Major Types of XSS
You'll commonly hear about:
1. Reflected XSS
2. Stored XSS
3. DOM-based XSSLet's understand each.
7. Reflected XSS
Reflected XSS occurs when malicious input is sent in a request and is immediately reflected into the response in an unsafe context.
Conceptually:
Browser
│
│ Input
▼
Server
│
│ Response containing input
▼
Browser
│
▼
HTML interpretedExample:
/search?q=USER_INPUTThe server generates a page containing that value.
8. Reflected XSS Example
Imagine:
/search?q=laptopThe application responds with:
<h2>Search results for: laptop</h2>If user-controlled content is inserted without appropriate encoding, the application may become vulnerable.
The security question is:
Does the application safely encode the value before placing it into the HTML response?
9. Stored XSS
Stored XSS is different.
The malicious input is stored by the application.
For example:
User
↓
Comment
↓
Database
↓
Web page
↓
Other user
↓
BrowserConceptually:
Input
↓
Stored
↓
Retrieved later
↓
Rendered
↓
BrowserThis can be especially serious because the unsafe content can affect multiple users.
10. Stored XSS Example
Imagine a comment system:
Name:
Rohit
Comment:
Hello everyone!The application stores:
Name
CommentLater:
Database
↓
Comments page
↓
BrowserIf the application renders stored content unsafely, every visitor to the affected page could potentially be exposed.
11. DOM-Based XSS
DOM-based XSS can happen entirely within client-side JavaScript.
Conceptually:
URL
↓
JavaScript
↓
DOM manipulation
↓
Browser interprets contentThe server may never receive the malicious value.
For example:
const value = location.hash;
element.innerHTML = value;The problem is that innerHTML interprets HTML markup.
12. Safer DOM Manipulation
Instead of:
element.innerHTML = userInput;prefer:
element.textContent = userInput;Why?
textContent treats the value as text rather than parsing it as HTML.
This is one of the most important XSS prevention concepts.
13. HTML Context
Consider:
<div>
USER_INPUT
</div>Here the input is inside an HTML element's text content.
The correct defense is generally:
HTML output encoding
14. Attribute Context
Now consider:
<input value="USER_INPUT">The context has changed.
You need appropriate attribute encoding and careful handling of the surrounding syntax.
This demonstrates an important rule:
XSS defenses depend on context.
15. JavaScript Context
Consider:
<script>
const name = "USER_INPUT";
</script>This is much more dangerous to construct dynamically.
The appropriate defense is not simply:
"escape everything"Instead, avoid placing untrusted data directly into executable JavaScript contexts.
Use safe data-transfer mechanisms and context-appropriate encoding.
16. URL Context
Another context:
<a href="USER_INPUT">
Open
</a>This requires URL validation and appropriate handling.
For example, applications should carefully restrict dangerous URL schemes when accepting user-controlled links.
17. The Context Matters
Think:
HTML text
≠
HTML attribute
≠
JavaScript
≠
CSS
≠
URLTherefore:
There is no universal "escape this string" function that is correct for every context.
18. XSS Testing Mindset
Don't start by throwing random payloads at every field.
Instead:
Identify input
↓
Find where it appears
↓
Determine context
↓
Establish baseline
↓
Use harmless test input
↓
Observe rendering
↓
Determine whether encoding occurs19. Start Your Lab
Linux
docker psWindows
docker psmacOS
docker psMake sure Juice Shop is running.
20. Test Juice Shop
Linux/macOS
curl -I http://127.0.0.1:3000Windows
curl.exe -I http://127.0.0.1:3000Then open:
http://127.0.0.1:300021. Start Burp Suite
Use:
Burp Suite
↓
Proxy
↓
Open BrowserKeep the target scope limited to:
127.0.0.1:3000🧪 Practical Lab 1
Find User-Controlled Input
Use Juice Shop normally.
Look for features such as:
Search
Reviews
Feedback
Comments
User profile
Product informationYour goal isn't exploitation yet.
Your goal is:
Find where your input appears in the application.
22. Example
Suppose you enter:
hello123and the page displays:
Search results for hello123Ask:
Where did my input appear?
HTML body?
Attribute?
JavaScript?
URL?
DOM?This is the beginning of XSS analysis.
23. Capture the Request
Open:
Proxy
↓
HTTP historyFind the request associated with your input.
Record:
Method:
Endpoint:
Parameter:
Input:
Response:24. Send to Repeater
Right-click:
Send to RepeaterThen send the original request.
This establishes your baseline.
25. Baseline
For example:
Input:
hello123
Response:
200 OK
Reflection:
hello123 appears in pageNow you know:
Input → Response26. Test Harmless HTML Characters
In your local lab, try a harmless marker such as:
xss-testThen try:
<test>The purpose is to determine whether the application:
Displays the charactersor:
Interprets them as markupDo not start with scripts.
27. What Should a Secure Application Do?
If you submit:
<test>a secure HTML-rendering context should generally display it as text:
<test>rather than creating an actual HTML element.
The browser should effectively receive encoded markup such as:
<test>when the content is intended to be displayed as text.
28. HTML Encoding
Important characters include:
< → <
> → >
& → &
" → "
' → appropriate context-specific encodingThe exact encoding requirements depend on the output context.
29. Why Encoding Works
Suppose the user provides:
<test>The application outputs:
<test>The browser displays:
<test>but doesn't interpret it as an HTML element.
So:
Input
↓
Encoding
↓
HTML
↓
Browser
↓
Text30. XSS Lab Observation
Create a table:
| Input | Appears in Response? | Encoded? | Browser Interpretation |
|---|---|---|---|
hello | Yes | N/A | Text |
<test> | ___ | ___ | ___ |
" | ___ | ___ | ___ |
' | ___ | ___ | ___ |
& | ___ | ___ | ___ |
This is more valuable than simply memorizing payloads.
31. Reflected XSS Analysis
Find an input that appears immediately in the response.
Your workflow:
Request
↓
Input
↓
Server
↓
Response
↓
Input reflected?
↓
Where?Then determine:
HTML text?
Attribute?
Script?
CSS?
URL?32. Stored XSS Analysis
If Juice Shop has a feature that stores your input:
Submit
↓
Stored
↓
Navigate away
↓
Return later
↓
Input still present?If yes:
Input
↓
Database/application storage
↓
Later renderingThat's the conceptual path of stored XSS.
33. DOM XSS Analysis
Open browser developer tools.
Look for JavaScript that reads:
location
location.search
location.hash
document.URL
document.referrerand passes values into dangerous DOM sinks such as:
innerHTML
outerHTML
insertAdjacentHTML
document.writeThis is a source → sink model.
34. XSS Source and Sink
A useful security model:
SOURCE
↓
Untrusted data enters JavaScript
↓
Processing
↓
SINK
↓
Browser interprets dataExamples of sources:
URL
Query string
Hash
Form input
StoragePotentially dangerous sinks include:
innerHTML
document.write
insertAdjacentHTML35. Safer Sink
Instead of:
element.innerHTML = value;use:
element.textContent = value;when you intend to display plain text.
This is an excellent secure-coding habit.
36. XSS and Cookies
Why is XSS dangerous?
A successful XSS vulnerability may allow malicious JavaScript to perform actions in the context of the victim's application session.
However, don't reduce XSS to:
"stealing cookies."
Modern applications may use:
HttpOnly cookies
SameSite cookies
Secure cookies
Token-based authentication
CSPSo the impact depends heavily on the application's architecture.
37. HttpOnly
A cookie can be configured with:
Set-Cookie: session=...; HttpOnlyHttpOnly prevents JavaScript from directly reading that cookie through document.cookie.
This can reduce some session-cookie theft risks from XSS.
But:
HttpOnly does not fix XSS.
Malicious JavaScript may still perform actions within the victim's browser context.
38. Secure Cookie
Another important attribute:
SecureThis tells browsers to send the cookie over secure HTTPS connections.
Again:
Secure cookie
≠
XSS protectionIt's defense in depth.
39. SameSite
Cookies can also use:
SameSiteto restrict certain cross-site cookie behavior.
Again:
SameSite
≠
XSS preventionDifferent security controls solve different problems.
40. Content Security Policy
CSP stands for:
Content Security Policy
A site can send a header such as:
Content-Security-Policy: ...CSP can restrict where scripts and other resources are allowed to load from.
A properly designed CSP can significantly reduce the impact of some XSS attacks.
But:
CSP should be defense in depth, not a replacement for safe output handling.
41. Secure XSS Architecture
A strong design looks like:
User Input
↓
Validation where appropriate
↓
Safe Storage
↓
Context-Aware Output Encoding
↓
Browser
+
CSP
+
Secure Cookies42. Linux Practical Commands
Check your lab:
docker psCheck the application:
curl -I http://127.0.0.1:3000Fetch the HTML:
curl -s http://127.0.0.1:3000/ | headSearch response headers for security-related headers:
curl -I http://127.0.0.1:3000/43. Windows Practical Commands
Check Docker:
docker psTest:
curl.exe -I http://127.0.0.1:3000Fetch HTML:
curl.exe -s http://127.0.0.1:3000/44. macOS Practical Commands
docker psThen:
curl -I http://127.0.0.1:3000Fetch:
curl -s http://127.0.0.1:3000/45. Search for Security Headers
Linux/macOS
curl -I http://127.0.0.1:3000 | grep -i "content-security-policy"Windows
curl.exe -I http://127.0.0.1:3000 | Select-String -Pattern "content-security-policy"If nothing appears, that simply means the header isn't present in that response.
It doesn't by itself prove the application is vulnerable.
46. Browser Developer Tools
Open:
Browser
↓
Developer Tools
↓
ElementsFind your input.
Then inspect:
HTML structure
Attributes
DOMNext:
Developer Tools
↓
Consoleand:
Sourcesto understand client-side JavaScript.
47. Look for Dangerous DOM Patterns
During source review, search for:
innerHTML =outerHTML =document.write(insertAdjacentHTML(These aren't automatically vulnerabilities.
The important question is:
Can attacker-controlled data reach the sink without appropriate sanitization or encoding?
48. Example Vulnerable JavaScript
const message = location.hash.substring(1);
document.getElementById("output").innerHTML = message;Flow:
URL hash
↓
message
↓
innerHTML
↓
DOMThis deserves security review.
49. Safer Version
const message = location.hash.substring(1);
document.getElementById("output").textContent = message;Now:
URL input
↓
textContent
↓
Plain text50. React / Frontend Frameworks
Modern frameworks often escape text by default.
For example, normal React rendering:
<div>{userInput}</div>is generally safer than deliberately injecting raw HTML.
But React also provides escape hatches such as:
dangerouslySetInnerHTMLWhenever you encounter APIs designed to inject raw HTML, perform a security review.
51. Laravel Blade
Blade normally escapes:
{{ $name }}This is preferable for ordinary text.
Be careful with:
{!! $name !!}because it intentionally outputs unescaped HTML.
Never use unescaped output simply because:
"It works."
Understand whether the content is trusted.
52. Spring / Thymeleaf
For server-rendered templates, use the framework's normal escaped text-output mechanisms.
Avoid deliberately rendering untrusted values as raw HTML.
The principle remains:
Untrusted input
↓
Context-aware encoding
↓
HTML53. XSS Code Review Checklist
When reviewing a web application, ask:
☐ Where does user input enter?
☐ Where is it stored?
☐ Where is it rendered?
☐ Which output context is used?
☐ Is it encoded?
☐ Is raw HTML allowed?
☐ Can user input reach innerHTML?
☐ Can it reach document.write?
☐ Is CSP configured?
☐ Are cookies protected?54. XSS vs CSRF
Don't confuse them.
XSS
Attacker-controlled script
↓
Victim's browserCSRF
Victim's browser
↓
Unintended authenticated requestXSS and CSRF are different vulnerabilities, although XSS can sometimes undermine CSRF defenses.
We'll study CSRF separately.
55. XSS Severity
XSS impact depends on:
Where?
Who is affected?
What privileges does the victim have?
Is it stored?
Can administrators encounter it?
What browser actions can be performed?
Are security controls present?Stored XSS in an administrative interface can be particularly serious.
56. Don't Test Real Users
If you discover a stored-input feature in your lab:
Your account
↓
Your test input
↓
Your local database
↓
Your browserKeep it there.
Never use another person's account or inject content into a production application without explicit authorization.
57. Day 18 Main Practical Exercise
Mission: Find an Input Reflection
Step 1
Open Juice Shop.
Step 2
Find a feature accepting text.
Step 3
Enter:
XSS-DAY18-TESTStep 4
Find the HTTP request in Burp.
Step 5
Send it to Repeater.
Step 6
Find your marker in the response.
Step 7
Determine its context:
HTML text
Attribute
JavaScript
URL
DOMStep 8
Try:
<test>Step 9
Determine whether it is:
Displayed as textor:
Interpreted as markupStep 10
Document your result.
📊 Day 18 Lab Report
╔══════════════════════════════════════╗
║ DAY 18 XSS LAB ║
╚══════════════════════════════════════╝
Target:
127.0.0.1:3000
Feature:
____________________
Endpoint:
____________________
HTTP Method:
____________________
Parameter:
____________________
Test Marker:
XSS-DAY18-TEST
Reflected?
Yes / No
Stored?
Yes / No / Unknown
Context:
HTML / Attribute / JS / DOM / Other
Special Character Test:
<test>
Encoded?
Yes / No / Unknown
Browser Interpretation:
____________________
Potential XSS?
Yes / No / Unclear
Evidence:
____________________
Recommended Fix:
____________________🧪 Day 18 Comparison Exercise
Create this table:
| Technique | Input Location | Stored? | Server Involved? | Main Concern |
|---|---|---|---|---|
| Reflected XSS | Request | Usually no | Yes | Immediate response |
| Stored XSS | Application storage | Yes | Usually | Other users |
| DOM XSS | Browser/DOM | Not necessarily | Not necessarily | Client-side JS |
🔐 XSS Prevention Checklist
Use:
✅ Context-aware output encoding
✅ Safe DOM APIs
✅ textContent instead of innerHTML for text
✅ Framework auto-escaping
✅ Avoid raw HTML where unnecessary
✅ Sanitize HTML when HTML is genuinely required
✅ Content Security Policy
✅ HttpOnly cookies
✅ Secure cookies
✅ SameSite cookies
✅ Input validation where appropriateOWASP's XSS prevention guidance emphasizes context-sensitive output encoding and safe handling of HTML/DOM content rather than relying on a single generic defense.
🚨 Common XSS Mistakes
Mistake 1
"I sanitized the input once, so it's safe everywhere."
Not necessarily.
Different contexts require different defenses.
Mistake 2
"I'll just remove
<script>."
Not a reliable security strategy.
XSS is broader than a particular tag.
Mistake 3
"CSP will fix everything."
No.
CSP is defense in depth.
Mistake 4
"HttpOnly prevents XSS."
No.
It primarily prevents JavaScript from directly reading cookies marked HttpOnly.
Mistake 5
"React/Laravel/Spring automatically makes everything safe."
Frameworks help, but unsafe APIs and raw HTML features can reintroduce risk.
📝 Day 18 Assignment
Answer these questions:
What does XSS stand for?
What is XSS?
What is reflected XSS?
What is stored XSS?
What is DOM-based XSS?
What is the difference between a source and a sink?
Why is
innerHTMLpotentially dangerous?Why is
textContentsafer for plain text?What is output encoding?
Why is context important when preventing XSS?
What does
HttpOnlydo?Does
HttpOnlyprevent XSS?What is CSP?
Is CSP a replacement for output encoding?
Why shouldn't you simply remove
<script>from user input?How can Laravel Blade help prevent XSS?
What is
dangerouslySetInnerHTML?Why can stored XSS be especially dangerous?
Why is DOM-based XSS different from reflected XSS?
Why must today's exercises remain inside your authorized lab?
🏆 Day 18 Challenge
Create your own XSS flow diagram:
USER INPUT
│
▼
WEB APPLICATION
│
┌──────────┴──────────┐
│ │
Reflected Stored
│ │
▼ ▼
RESPONSE DATABASE
│ │
└──────────┬──────────┘
▼
BROWSER
│
▼
HTML / DOM
│
▼
JavaScript ContextThen add the defense layer:
Input
↓
Validation where appropriate
↓
Safe processing
↓
Context-aware output encoding
↓
Safe DOM APIs
↓
CSP
↓
Browser🔑 Day 18 Golden Rule
Never treat untrusted data as executable HTML or JavaScript.
Remember:
DATA ≠ CODEThat's the fundamental security principle behind both:
SQL Injectionand:
XSSIn SQLi:
Data → SQL codeIn XSS:
Data → HTML/JavaScriptThe defense is to maintain a strong separation between untrusted data and executable syntax.
📚 Day 18 Summary
Today you learned:
XSS
Reflected XSS
Stored XSS
DOM-based XSS
HTML contexts
Attribute contexts
JavaScript contexts
DOM sources
DOM sinks
innerHTMLtextContentOutput encoding
CSP
HttpOnly
Secure cookies
SameSite
XSS code review
Laravel Blade
Spring/Thymeleaf
React
Linux commands
Windows commands
macOS commands
Burp Suite testing methodology
Most Important Lesson
Untrusted Data
↓
Context-Aware Encoding
↓
Safe HTML/DOM
↓
Browser🔐 LEARN → TEST ONLY YOUR LAB → UNDERSTAND → FIX → SECURE.
🔜 Day 19 — XSS Deep Dive & Safe Lab Analysis
Next we'll go deeper into:
Finding reflection points
HTML vs attribute contexts
Stored XSS analysis
DOM XSS source → sink tracing
Browser Developer Tools
Burp Repeater
Safe XSS validation
Output encoding
Sanitization
CSP
Secure JavaScript
Laravel, Spring Boot and frontend defenses
Linux, Windows and macOS practical exercises
⚠️ LEARNING PURPOSE ONLY: Every practical exercise will continue to use your local/authorized lab environment.
%20Fundamentals%20%7C%20Day%2018.png)
No comments:
Post a Comment