![]() |
| Ethical Hacking |
🛡️ Ethical Hacking — Day 20
XSS Practical Lab, Source-to-Sink Analysis & Remediation
⚠️ LEARNING PURPOSE ONLY: This tutorial is strictly for educational and defensive cybersecurity learning. Perform all practical exercises only against your local OWASP Juice Shop lab, applications you own, or systems for which you have explicit authorization. Never test XSS against public websites, production applications, or other users without permission.
Welcome to Day 20.
For the last two days, you've learned XSS fundamentals and how to trace input through the browser. Today we'll combine those concepts into a structured XSS assessment workflow.
The goal is:
Find
↓
Trace
↓
Understand
↓
Validate minimally
↓
Document
↓
FixNot:
Find
↓
Exploit everything🎯 Day 20 Learning Objectives
Today you'll practice:
Reflected XSS analysis
Stored XSS analysis
DOM XSS analysis
Source → sink tracing
Burp Suite Repeater
Browser Developer Tools
Response comparison
HTML encoding
JavaScript-safe DOM APIs
Sanitization
CSP
Secure cookies
Laravel XSS prevention
Spring Boot/Thymeleaf prevention
React prevention
Linux commands
Windows PowerShell commands
macOS commands
XSS vulnerability reporting
1. The XSS Assessment Model
Use this model throughout today's lab:
INPUT
│
▼
┌──────────────┐
│ Application │
└──────┬───────┘
│
┌───────┴────────┐
│ │
Server Browser
│ │
▼ ▼
Response DOM / JS
│ │
└───────┬────────┘
▼
HTML Context
│
▼
BrowserYour primary question is:
Can untrusted data reach an executable HTML/JavaScript context without appropriate protection?
2. Start Juice Shop
Linux
docker psWindows PowerShell
docker psmacOS
docker psIf your Juice Shop container isn't running:
docker start <container-id>Then verify.
Linux/macOS
curl -I http://127.0.0.1:3000Windows
curl.exe -I http://127.0.0.1:30003. Start Burp Suite
Open:
Burp Suite
↓
Proxy
↓
Open BrowserOpen:
http://127.0.0.1:3000Keep the scope restricted to:
127.0.0.1:30004. Today's Test Marker
Use a unique harmless marker:
XSS-DAY20-TESTWhy?
Because a unique marker makes it easy to determine:
Where did my input go?🧪 Practical Lab 1 — Reflected Input
Step 1
Find a feature accepting input.
For example:
SearchEnter:
XSS-DAY20-TESTStep 2
Open:
Proxy
↓
HTTP historyFind the request.
Record:
Method:
Endpoint:
Parameter:
Value:Step 3
Send it to:
RepeaterSend the original request.
This is your baseline.
5. Find the Reflection
In Burp response, search:
XSS-DAY20-TESTIf you find it, inspect the surrounding HTML.
Example A
<div>XSS-DAY20-TEST</div>This is:
HTML text contextExample B
<input value="XSS-DAY20-TEST">This is:
Attribute contextExample C
const search = "XSS-DAY20-TEST";This is:
JavaScript context6. Reflection Table
Complete this:
| Parameter | Reflected? | Context | Encoded? |
|---|---|---|---|
| Search | Yes/No | HTML/Attribute/JS | Yes/No |
| Feedback | Yes/No | ___ | ___ |
| Other | Yes/No | ___ | ___ |
Remember:
Reflection by itself does not prove XSS.
7. Safe Character Testing
Use harmless test values such as:
XSS-DAY20-TESTThen:
<test>Then:
"test"Then:
'test'Then:
&testObserve whether the application:
Displays them as textor:
Treats them as markup8. What Secure HTML Output Looks Like
If the application intends to display:
<test>it may encode it as:
<test>The browser then displays:
<test>as ordinary text.
The important distinction is:
Visible text
≠
Executable markup9. Practical Lab 2 — Browser Inspection
Open Developer Tools:
F12or:
Right Click
↓
InspectGo to:
ElementsSearch:
XSS-DAY20-TESTDetermine:
HTML element?
Attribute?
Script?
DOM-generated content?10. HTTP Response vs DOM
This is an important distinction.
Your marker may not appear in the original HTTP response but may appear in the DOM.
For example:
HTTP Response
│
▼
JavaScript
│
▼
DOM
│
▼
Visible PageThis can indicate client-side processing.
That's where DOM XSS analysis begins.
11. Practical Lab 3 — DOM Analysis
Open:
Developer Tools
↓
SourcesSearch JavaScript source for:
location.searchlocation.hashdocument.URLdocument.referrerThese can be sources of browser-controlled data.
12. Search for Sinks
Search JavaScript for:
innerHTMLouterHTMLdocument.writeinsertAdjacentHTMLThese can be potentially dangerous sinks depending on the data reaching them.
13. Source → Sink
Your goal is to determine whether this flow exists:
SOURCE
↓
Untrusted Data
↓
Processing
↓
Dangerous SinkFor example:
location.hash
↓
variable
↓
innerHTML
↓
DOMThat requires security review.
14. Safe DOM Example
Risky for untrusted text
element.innerHTML = userInput;Safer for plain text
element.textContent = userInput;Why?
Because:
innerHTML
→ HTML interpretationwhile:
textContent
→ Text15. Practical Lab 4 — Stored Input
Now look for a Juice Shop feature where data is saved.
Possible examples include:
Reviews
Feedback
Profile information
CommentsEnter:
XSS-DAY20-STOREDSubmit it.
Then:
Navigate away
↓
Return to page
↓
Is the value still present?If yes, you've observed a storage flow.
16. Stored XSS Flow
Conceptually:
User Input
↓
Application
↓
Storage
↓
Database
↓
Later Request
↓
HTML Response
↓
BrowserThis is why stored XSS can potentially affect other users.
For today's lab:
Use only your own local test data.
17. Stored Doesn't Automatically Mean XSS
Suppose the application stores:
<test>and later displays:
<test>That's good.
So:
Stored Input
≠
Stored XSSYou must determine how the value is rendered.
18. Practical Lab 5 — DOM XSS
Look for client-side code that does something like:
const value = location.hash.substring(1);Then check whether that value eventually reaches:
innerHTMLor another HTML-interpreting sink.
Your analysis should be:
Source:
_____________
Processing:
_____________
Sink:
_____________
Encoding/sanitization:
_____________
Conclusion:
_____________19. Response Comparison
For each test, record:
| Test | Status | Length | Reflection | Encoding |
|---|---|---|---|---|
| Normal | ___ | ___ | ___ | ___ |
| Marker | ___ | ___ | ___ | ___ |
<test> | ___ | ___ | ___ | ___ |
"test" | ___ | ___ | ___ | ___ |
'test' | ___ | ___ | ___ | ___ |
This develops a professional testing habit:
Measure first. Conclude second.
20. Linux Practical Session
Check Docker:
docker psCheck Juice Shop:
curl -I http://127.0.0.1:3000Save the page:
curl -s http://127.0.0.1:3000/ > juice.htmlSearch your marker:
grep -n "XSS-DAY20-TEST" juice.htmlSearch for CSP:
curl -I http://127.0.0.1:3000/ | grep -i "content-security-policy"21. Windows Practical Session
Check Docker:
docker psCheck Juice Shop:
curl.exe -I http://127.0.0.1:3000Save HTML:
curl.exe -s http://127.0.0.1:3000/ -o juice.htmlSearch marker:
Select-String -Path juice.html -Pattern "XSS-DAY20-TEST"Check CSP:
curl.exe -I http://127.0.0.1:3000/ |
Select-String -Pattern "content-security-policy"22. macOS Practical Session
Check:
docker psTest:
curl -I http://127.0.0.1:3000Save:
curl -s http://127.0.0.1:3000/ > juice.htmlSearch:
grep -n "XSS-DAY20-TEST" juice.htmlCheck CSP:
curl -I http://127.0.0.1:3000/ | grep -i "content-security-policy"23. Through Burp
You can send your local request through Burp.
Linux/macOS
curl -x http://127.0.0.1:8080 \
"http://127.0.0.1:3000/"Windows
curl.exe -x http://127.0.0.1:8080 `
"http://127.0.0.1:3000/"Flow:
curl
↓
Burp Proxy :8080
↓
Juice Shop :300024. CSP Check
Run:
curl -I http://127.0.0.1:3000Look for:
Content-Security-PolicyA CSP may contain directives such as:
default-src
script-src
object-src
style-src
img-src
connect-src
frame-ancestorsThe exact policy should be designed according to the application's requirements.
25. Example CSP
A simplified example:
Content-Security-Policy:
default-src 'self';
object-src 'none';
frame-ancestors 'none';This is only an illustrative example, not a universal policy.
A real application needs a CSP tailored to its legitimate scripts, APIs, styles, images, and other resources.
26. Secure Cookies
Inspect your application's cookies.
Look for:
HttpOnly
Secure
SameSiteConceptually:
HttpOnly
↓
Reduce direct JS cookie access
Secure
↓
HTTPS-only cookie transmission
SameSite
↓
Restrict certain cross-site cookie behaviorThese are defense-in-depth controls.
27. Laravel Defense
Good
{{ $name }}Blade escapes normal output.
Potentially dangerous
{!! $name !!}This deliberately outputs unescaped content.
If HTML is required, sanitize it appropriately before rendering.
28. Spring Boot / Thymeleaf
Prefer normal escaped template output.
Be careful with mechanisms that intentionally render raw HTML.
The principle is:
Untrusted Data
↓
Context-Aware Encoding
↓
HTML29. React Defense
Normal rendering:
<div>{userInput}</div>is generally escaped.
Review carefully:
<div
dangerouslySetInnerHTML={{__html: userInput}}
/>If raw HTML is genuinely required:
User Input
↓
Trusted?
↓
Sanitize
↓
Controlled HTML30. JavaScript Defense
Avoid for untrusted HTML:
element.innerHTML = userInput;Prefer for text:
element.textContent = userInput;Also review:
document.write()and:
insertAdjacentHTML()when they receive user-controlled data.
31. Output Encoding
For HTML text, characters such as:
<
>
&
"
'may need context-appropriate encoding.
Example:
<test>becomes:
<test>The browser then displays:
<test>as text.
32. Input Validation
Input validation is useful for enforcing application rules.
For example:
Username:
Allowed → letters/numbers
Age:
Allowed → integer
Sort:
Allowed → predefined valuesBut:
Input validation is not a substitute for correct output encoding.
An input can be perfectly valid according to business rules and still need encoding when inserted into HTML.
33. Sanitization
If your application genuinely needs HTML:
Rich Text Editor
↓
User HTML
↓
HTML Sanitizer
↓
Allowed HTML
↓
BrowserDon't create your own blacklist such as:
Remove <script>and assume the problem is solved.
34. XSS Severity
When reporting XSS, consider:
Where is it?
Who can trigger it?
Who sees it?
Is it stored?
Can an administrator encounter it?
What privileges does the victim have?
Can it affect authenticated actions?Don't simply write:
"XSS = Critical."
Severity depends on context and impact.
35. Example Security Finding
Title
Potential Reflected XSS in Search Parameter
Location
Endpoint: /example
Parameter: qObservation
User-controlled input is reflected into an HTML context.
Risk
If the value is rendered without appropriate output encoding, an attacker could potentially cause unintended browser-side script execution.
Recommendation
Use context-appropriate output encoding and avoid inserting untrusted input into raw HTML/JavaScript contexts.
36. Evidence
Good evidence:
Request
↓
Parameter
↓
Input
↓
Response
↓
Reflection Context
↓
Browser BehaviorDon't collect unnecessary personal or production data.
For your training report, use:
127.0.0.1and your own test account/data.
37. Day 20 Professional Workflow
Memorize:
1. Permission
↓
2. Scope
↓
3. Identify Input
↓
4. Establish Baseline
↓
5. Capture Request
↓
6. Find Reflection
↓
7. Determine Context
↓
8. Trace Source → Sink
↓
9. Validate Minimally
↓
10. Document
↓
11. Fix
↓
12. Retest🧪 Day 20 Final Challenge
Choose one Juice Shop feature.
Investigate it completely.
Part A — HTTP
Record:
Method:
Endpoint:
Parameter:
Normal input:
Test input:
Status:
Response length:Part B — Reflection
Determine:
Reflected?
Stored?
DOM-generated?Part C — Context
Determine:
HTML
Attribute
JavaScript
URL
DOMPart D — Source/Sink
If client-side JavaScript is involved:
Source:
Processing:
Sink:Part E — Defense
Determine:
Encoding:
Sanitization:
Safe DOM API:
CSP:
Cookie protections:📊 Day 20 Complete Lab Report
╔══════════════════════════════════════╗
║ DAY 20 — XSS ASSESSMENT ║
╚══════════════════════════════════════╝
Target:
127.0.0.1:3000
Feature:
____________________________
Endpoint:
____________________________
HTTP Method:
____________________________
Parameter:
____________________________
Baseline Input:
____________________________
Test Input:
____________________________
Status:
____________________________
Response Length:
____________________________
Reflection:
Yes / No
Storage:
Yes / No / Unknown
DOM Processing:
Yes / No / Unknown
Context:
____________________________
Source:
____________________________
Sink:
____________________________
Encoding:
____________________________
Sanitization:
____________________________
CSP:
Present / Missing / Unknown
Cookie Protections:
____________________________
Potential Vulnerability:
____________________________
Evidence:
____________________________
Impact:
____________________________
Recommended Fix:
____________________________
Retest Result:
____________________________📝 Day 20 Assignment
Answer these:
What is a reflection point?
Does reflection automatically mean XSS?
How do you determine the output context?
What is a source?
What is a sink?
Why is
innerHTMLpotentially dangerous?Why is
textContentsafer for plain text?What is the difference between reflected and stored XSS?
What is DOM-based XSS?
Why should you establish a baseline?
Why should only one parameter be changed at a time?
What is context-aware output encoding?
What is HTML sanitization?
Why isn't removing
<script>sufficient?What does CSP provide?
What does
HttpOnlydo?Why is
Secureuseful for cookies?Why is
SameSiteuseful?Why should raw HTML rendering be reviewed carefully?
What information should an XSS report contain?
🏆 Day 20 Golden Rule
The most important lesson from Days 18–20:
UNTRUSTED DATA
│
▼
SOURCE
│
▼
APPLICATION
│
┌─────────┴─────────┐
│ │
SAFE OUTPUT DANGEROUS SINK
│ │
▼ ▼
ENCODE REVIEW/FIX
│ │
└─────────┬─────────┘
▼
BROWSERRemember:
DATA ≠ CODE
And the professional mindset is:
Find → Understand → Validate → Document → Fix → Retest.
🔐 Ethical Hacking Rule — Day 20
LEARNING PURPOSE ONLY: All practical commands and XSS exercises in this course are intended for your local/authorized lab environment. Do not test public websites, production applications, or other people's accounts without explicit authorization.
📚 Day 20 Summary
Today you practiced:
Reflected XSS
Stored XSS
DOM XSS
Reflection analysis
HTML contexts
Source → sink analysis
Burp Repeater
Browser Developer Tools
Safe XSS validation
HTML encoding
Sanitization
CSP
Secure cookies
Laravel
Spring Boot
React
JavaScript security
Linux
Windows
macOS
Security reporting
Remediation and retesting
🔑 The key skill
Don't ask:
"Which XSS payload should I use?"
Ask:
"Where does this untrusted data go, what context does it reach, and what security control protects that context?"
🔜 Day 21 — Authentication & Password Security
Tomorrow we'll start a new major web-security topic:
Authentication vs authorization
Login security
Password hashing
Password storage
Brute-force concepts
Account lockout
Rate limiting
Session management
Cookies
MFA
Secure login implementation
Burp authentication analysis
Linux, Windows & macOS practical exercises
OWASP Juice Shop lab
⚠️ LEARNING PURPOSE ONLY: Practical authentication testing will remain restricted to your own local/authorized lab.

No comments:
Post a Comment