chat

是什么?

好的,咱们把 XSS 攻击一次讲透,从“是什么 → 怎么发生 → 有哪些类型 → 有多危险 → 如何防 → 实战最佳实践”全程打通。


一、什么是 XSS?

XSS(Cross-Site Scripting,跨站脚本攻击) 简单说就是:

攻击者把恶意 JavaScript 注入到页面中,当其他用户访问页面时,这段脚本就在他们浏览器中执行。

本质: 浏览器“信任了不该信任的内容”,把用户输入当成了代码执行。

核心公式:

用户输入 → 未过滤 → 直接渲染到页面 → 浏览器执行

二、XSS 能干什么?(为什么危险)

XSS 不只是弹个 alert,它是真·高危漏洞:

能力 实际后果
读取 Cookie / Token 劫持登录态,直接接管账号
模拟用户操作 自动发帖、转账、改资料
页面钓鱼 嵌入假登录框骗密码
远程加载木马 植入键盘记录,长期监控
绕过权限系统 构造后台请求

✅ 在企业系统里: XSS = 管理员权限沦陷 = 数据泄露 / 系统失控


三、XSS 的三大类型

1. 反射型 XSS(Reflected)

用户输入的数据立刻返回到页面中。

典型场景:

/search?keyword=<script>恶意代码</script>

页面直接渲染 keyword,就被执行。

特点:

  • 需要诱导点击链接
  • 不持久
  • 常见于搜索、错误页面

2. 存储型 XSS(Stored)

恶意代码被存进数据库,所有访问者都会中招。

比如:

  • 评论区
  • 用户昵称
  • 个人简介

攻击者提交:

<script>...</script>

后台存了,所有人加载页面就执行。

✅ 最危险的一种


3. DOM 型 XSS

不是后端问题,而是前端 JS 逻辑问题。

例如:

document.getElementById("box").innerHTML = location.hash;

攻击者构造 URL:

http://xxx.com/#<script>代码</script>

浏览器自己执行,服务器完全不知情。


四、XSS 常见触发点

🚩 高危位置:

  • v-html
  • innerHTML
  • eval()
  • setTimeout(“字符串”)
  • new Function()
  • document.write()
  • location.href 动态拼接

🚩 高风险输入源:

  • URL 参数
  • 表单内容
  • 评论、富文本
  • Cookie
  • localStorage
  • WebSocket 推送

五、典型 XSS 漏洞示例

危险写法(Vue):

<div v-html="userInput"></div>

如果 userInput = <script>steal()</script> 你网页就变攻击平台了。

危险写法(JS):

element.innerHTML = userContent;

六、XSS 防御核心原则

一句话总结:

所有用户输入都是不可信的 所有输出都必须转义

四大防御策略:

  1. ✅ 输出时统一转义(核心)
  2. ✅ 不信任任何输入
  3. ✅ 避免动态执行 JS
  4. ✅ 强制 CSP 内容安全策略

七、XSS 防御的黄金公式

✅ 正确思想

场景 正确做法
普通文本 转义显示
HTML内容 白名单过滤
JSON数据 严格序列化
URL encodeURIComponent

八、前端 Vue3 防 XSS 实战

1. 永远避免 v-html

❌ 错误:

<div v-html="content"></div>

✅ 安全:

<div><!-- Post Header -->
<header class="intro-header" style="background-image: url('/static/app/res/img/home-bg.jpeg')" >
  <div class="container">
    <div class="row">
      <div class="col-lg-10 col-lg-offset-1 col-md-10 col-md-offset-1">
        <div class="post-heading">
          <div class="tags">
            
            <a class="tag" href="/tags/#plateform" title="plateform">plateform</a>
            
            <a class="tag" href="/tags/#sh" title="sh">sh</a>
            
          </div>
          <h1>权限体系之-20-passport 安全攻击有哪些?</h1>
          
          
          <h2 class="subheading"></h2>
          
          <span class="meta">
            Posted by
                    <a class="my-aw" href="/about/">houbb</a>
            on November 20, 2025
          </span>
        </div>
      </div>
    </div>
  </div>
</header>


<article class="post" itemscope itemtype="http://schema.org/BlogPosting">

  <div class="container" style="overflow-y:hidden;">
    <div class="row">
      <div class="col-lg-10 col-lg-offset-1 col-md-10 col-md-offset-1 post-container">

        <div class="post-content" itemprop="articleBody" style="min-height: 420px;">
          <h1 id="chat">chat</h1>

<h2 id="类似-xss-的攻击有哪些">类似 XSS 的攻击有哪些?</h2>

<p>很好,这个问题问得非常“安全架构层级” 👍
如果说 <strong>XSS 是前端最典型的注入攻击</strong>,那它只是冰山一角。和 XSS 同一“家族”的攻击,其实是一个完整的攻击谱系。</p>

<p>我给你按「攻击本质」分类,帮你建立一套安全认知地图。</p>

<hr />

<h1 id="一和-xss-同级的注入类攻击最危险家族">一、和 XSS 同级的“注入类攻击”(最危险家族)</h1>

<p>它们的共同点:</p>

<blockquote>
  <p>把恶意内容当成指令执行</p>
</blockquote>

<h2 id="1-sql-注入sql-injection">1. SQL 注入(SQL Injection)</h2>

<p>把用户输入拼接进 SQL 语句。</p>

<p>例子原理:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>用户名: admin' OR '1'='1
</code></pre></div></div>

<p>危害:</p>

<ul>
  <li>数据库被拖库</li>
  <li>数据篡改</li>
  <li>权限绕过</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>PreparedStatement</li>
  <li>ORM 参数绑定</li>
  <li>禁止字符串拼接 SQL</li>
</ul>

<hr />

<h2 id="2-os-命令注入command-injection">2. OS 命令注入(Command Injection)</h2>

<p>攻击者让服务器执行系统命令:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>; rm -rf /
</code></pre></div></div>

<p>常见场景:</p>

<ul>
  <li>调用 shell 执行命令</li>
  <li>文件处理系统</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>禁止拼接 shell 命令</li>
  <li>使用白名单参数</li>
  <li>最小权限原则</li>
</ul>

<hr />

<h2 id="3-ldap-注入">3. LDAP 注入</h2>

<p>类似 SQL,只不过目标是 LDAP 目录服务。</p>

<p>危害:</p>

<ul>
  <li>绕过认证</li>
  <li>获取组织架构、用户信息</li>
</ul>

<hr />

<h2 id="4-xpath-注入">4. XPath 注入</h2>

<p>针对 XML 查询语言的注入攻击:</p>

<ul>
  <li>常见于老系统、政企系统</li>
</ul>

<hr />

<h1 id="二web-权限类攻击">二、Web 权限类攻击</h1>

<h2 id="5-csrf跨站请求伪造">5. CSRF(跨站请求伪造)</h2>

<p>伪造用户身份发请求:</p>

<p>场景:
用户登录状态下访问恶意网站 → 自动向你系统发请求。</p>

<p>危险操作:</p>

<ul>
  <li>转账</li>
  <li>修改密码</li>
  <li>删除数据</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>CSRF Token</li>
  <li>SameSite Cookie</li>
  <li>Referer 校验</li>
</ul>

<hr />

<h2 id="6-idor越权访问">6. IDOR(越权访问)</h2>

<p>直接修改参数获取他人数据:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/api/order?id=10001 → 改成 10002
</code></pre></div></div>

<p>危害:</p>

<ul>
  <li>任意查看他人数据</li>
  <li>修改他人资源</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>每次校验当前用户权限</li>
  <li>不能只靠前端控制</li>
</ul>

<hr />

<h2 id="7-逻辑漏洞攻击">7. 逻辑漏洞攻击</h2>

<p>利用业务规则盲区:</p>

<ul>
  <li>重复领取优惠券</li>
  <li>越界操作</li>
  <li>多次退款</li>
</ul>

<p>这是安全中最难防的一类,非常常见。</p>

<hr />

<h1 id="三浏览器与前端相关攻击">三、浏览器与前端相关攻击</h1>

<h2 id="8-clickjacking点击劫持">8. Clickjacking(点击劫持)</h2>

<p>覆盖透明 iframe,引诱用户点击:</p>

<ul>
  <li>用户以为点 A,实际上点 B</li>
</ul>

<p>✅ 防御:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>X-Frame-Options: DENY
</code></pre></div></div>

<hr />

<h2 id="9-dom-型攻击">9. DOM 型攻击</h2>

<p>类似 XSS,但在浏览器 JS 中产生:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">location</span><span class="p">.</span><span class="nx">hash</span> <span class="nx">注入</span>
<span class="nx">innerHTML</span> <span class="nx">拼接</span>
</code></pre></div></div>

<hr />

<h1 id="四会话与身份攻击">四、会话与身份攻击</h1>

<h2 id="10-session-劫持">10. Session 劫持</h2>

<p>通过:</p>

<ul>
  <li>XSS + Cookie 窃取</li>
  <li>网络中间人</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>HttpOnly</li>
  <li>Secure Cookie</li>
  <li>HTTPS</li>
</ul>

<hr />

<h2 id="11-重放攻击replay">11. 重放攻击(Replay)</h2>

<p>截获请求包重复发送。</p>

<p>常见于:</p>

<ul>
  <li>登录</li>
  <li>支付接口</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>nonce + timestamp</li>
  <li>请求签名</li>
</ul>

<hr />

<h2 id="12-暴力破解--撞库">12. 暴力破解 &amp; 撞库</h2>

<ul>
  <li>密码组合爆破</li>
  <li>数据库泄露后的账号尝试</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>登录限流</li>
  <li>验证码</li>
  <li>失败锁定</li>
</ul>

<hr />

<h1 id="五供应链攻击">五、供应链攻击</h1>

<h2 id="13-依赖投毒">13. 依赖投毒</h2>

<p>篡改第三方库代码:</p>

<ul>
  <li>NPM 后门事件</li>
  <li>OpenSSL 漏洞</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>依赖审计</li>
  <li>锁版本</li>
  <li>SBOM</li>
</ul>

<hr />

<h1 id="六文件与上传攻击">六、文件与上传攻击</h1>

<h2 id="14-文件上传漏洞">14. 文件上传漏洞</h2>

<p>上传:</p>

<ul>
  <li>WebShell</li>
  <li>木马脚本</li>
</ul>

<p>✅ 防御:</p>

<ul>
  <li>严格限制扩展名</li>
  <li>MIME 验证</li>
  <li>存储隔离</li>
</ul>

<hr />

<h1 id="七信息泄露类攻击">七、信息泄露类攻击</h1>

<h2 id="15-敏感信息泄露">15. 敏感信息泄露</h2>

<ul>
  <li>配置文件暴露</li>
  <li>日志打印密码</li>
  <li>接口直接返回密钥</li>
</ul>

<hr />

<h1 id="八综合对比xss-在攻击体系中的位置">八、综合对比:XSS 在攻击体系中的位置</h1>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>安全攻击谱系图:

注入类:
  ├── XSS
  ├── SQL Injection
  ├── Command Injection
  └── LDAP 注入

会话类:
  ├── CSRF
  ├── Session Hijacking
  └── Replay

授权类:
  ├── IDOR
  └── 越权访问

客户端类:
  ├── Clickjacking
  └── DOM-based 攻击
</code></pre></div></div>

<hr />

<h1 id="九企业级常见-top-10-攻击实战高频">九、企业级常见 Top 10 攻击(实战高频)</h1>

<p>来自 OWASP Top 10 常见组合:</p>

<ol>
  <li>XSS</li>
  <li>SQL 注入</li>
  <li>CSRF</li>
  <li>文件上传漏洞</li>
  <li>未授权访问</li>
  <li>逻辑漏洞</li>
  <li>会话固定</li>
  <li>信息泄露</li>
  <li>SSRF</li>
  <li>依赖组件漏洞</li>
</ol>

<hr />

<h1 id="十你该如何构建系统级防护">十、你该如何构建系统级防护</h1>

<p>如果你是做平台架构,我建议建立四层安全体系:</p>

<table>
  <thead>
    <tr>
      <th>层级</th>
      <th>防护重点</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>前端</td>
      <td>输入过滤 + CSP</td>
    </tr>
    <tr>
      <td>接口</td>
      <td>参数校验 + Token</td>
    </tr>
    <tr>
      <td>服务</td>
      <td>权限控制 + 认证</td>
    </tr>
    <tr>
      <td>数据</td>
      <td>加密 + 审计</td>
    </tr>
  </tbody>
</table>

<hr />

<h1 id="简单总结">简单总结</h1>

<p>可以把“类似 XSS 的攻击”理解为:</p>

<blockquote>
  <p>一切把数据当代码执行的攻击
一切利用用户信任和系统漏洞的攻击</p>
</blockquote>

<p>XSS = 浏览器执行代码
SQL 注入 = 数据库执行代码
命令注入 = 操作系统执行代码</p>

<p>本质都是:<strong>执行了不该执行的东西</strong></p>

<ul id="markdown-toc">
  <li><a href="#chat" id="markdown-toc-chat">chat</a>    <ul>
      <li><a href="#类似-xss-的攻击有哪些" id="markdown-toc-类似-xss-的攻击有哪些">类似 XSS 的攻击有哪些?</a></li>
    </ul>
  </li>
  <li><a href="#一和-xss-同级的注入类攻击最危险家族" id="markdown-toc-一和-xss-同级的注入类攻击最危险家族">一、和 XSS 同级的“注入类攻击”(最危险家族)</a>    <ul>
      <li><a href="#1-sql-注入sql-injection" id="markdown-toc-1-sql-注入sql-injection">1. SQL 注入(SQL Injection)</a></li>
      <li><a href="#2-os-命令注入command-injection" id="markdown-toc-2-os-命令注入command-injection">2. OS 命令注入(Command Injection)</a></li>
      <li><a href="#3-ldap-注入" id="markdown-toc-3-ldap-注入">3. LDAP 注入</a></li>
      <li><a href="#4-xpath-注入" id="markdown-toc-4-xpath-注入">4. XPath 注入</a></li>
    </ul>
  </li>
  <li><a href="#二web-权限类攻击" id="markdown-toc-二web-权限类攻击">二、Web 权限类攻击</a>    <ul>
      <li><a href="#5-csrf跨站请求伪造" id="markdown-toc-5-csrf跨站请求伪造">5. CSRF(跨站请求伪造)</a></li>
      <li><a href="#6-idor越权访问" id="markdown-toc-6-idor越权访问">6. IDOR(越权访问)</a></li>
      <li><a href="#7-逻辑漏洞攻击" id="markdown-toc-7-逻辑漏洞攻击">7. 逻辑漏洞攻击</a></li>
    </ul>
  </li>
  <li><a href="#三浏览器与前端相关攻击" id="markdown-toc-三浏览器与前端相关攻击">三、浏览器与前端相关攻击</a>    <ul>
      <li><a href="#8-clickjacking点击劫持" id="markdown-toc-8-clickjacking点击劫持">8. Clickjacking(点击劫持)</a></li>
      <li><a href="#9-dom-型攻击" id="markdown-toc-9-dom-型攻击">9. DOM 型攻击</a></li>
    </ul>
  </li>
  <li><a href="#四会话与身份攻击" id="markdown-toc-四会话与身份攻击">四、会话与身份攻击</a>    <ul>
      <li><a href="#10-session-劫持" id="markdown-toc-10-session-劫持">10. Session 劫持</a></li>
      <li><a href="#11-重放攻击replay" id="markdown-toc-11-重放攻击replay">11. 重放攻击(Replay)</a></li>
      <li><a href="#12-暴力破解--撞库" id="markdown-toc-12-暴力破解--撞库">12. 暴力破解 &amp; 撞库</a></li>
    </ul>
  </li>
  <li><a href="#五供应链攻击" id="markdown-toc-五供应链攻击">五、供应链攻击</a>    <ul>
      <li><a href="#13-依赖投毒" id="markdown-toc-13-依赖投毒">13. 依赖投毒</a></li>
    </ul>
  </li>
  <li><a href="#六文件与上传攻击" id="markdown-toc-六文件与上传攻击">六、文件与上传攻击</a>    <ul>
      <li><a href="#14-文件上传漏洞" id="markdown-toc-14-文件上传漏洞">14. 文件上传漏洞</a></li>
    </ul>
  </li>
  <li><a href="#七信息泄露类攻击" id="markdown-toc-七信息泄露类攻击">七、信息泄露类攻击</a>    <ul>
      <li><a href="#15-敏感信息泄露" id="markdown-toc-15-敏感信息泄露">15. 敏感信息泄露</a></li>
    </ul>
  </li>
  <li><a href="#八综合对比xss-在攻击体系中的位置" id="markdown-toc-八综合对比xss-在攻击体系中的位置">八、综合对比:XSS 在攻击体系中的位置</a></li>
  <li><a href="#九企业级常见-top-10-攻击实战高频" id="markdown-toc-九企业级常见-top-10-攻击实战高频">九、企业级常见 Top 10 攻击(实战高频)</a></li>
  <li><a href="#十你该如何构建系统级防护" id="markdown-toc-十你该如何构建系统级防护">十、你该如何构建系统级防护</a></li>
  <li><a href="#简单总结" id="markdown-toc-简单总结">简单总结</a></li>
</ul>

        </div>

        <div class="more-learn-wrapper">
          <h2 id="更多学习">更多学习</h2>
          <li>
            <a class="my-a" href="https://github.com/houbb"><span class="icon icon--github"><svg viewBox="0 0 16 16"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/></svg>
</span>&nbsp;个人 Github</a>
          </li>
          <li>
            <i class="fa fa-fw fa-wechat text-muted" title="wechat"></i>&nbsp;个人公众号
          </li>
          <p>更多实时资讯,前沿技术,生活趣事。尽在【老马啸西风】</p>
          <p>交流社群:<a href="https://mp.weixin.qq.com/s/rkSvXxiiLGjl3S-ZOZCr0Q">交流群信息</a></p>
          <p><img src="/SIGN.png" alt="image" /></p>
        </div>

        <!--文章上下篇 START-->
        <nav class="article-page-warp" style="margin-top: 20px;">
          <div class="pagination-list">
            
            <a class="prev pull-left my-a" href="/2025/11/20/sso-21-passport-log4j2" rel="bookmark">
              <i class="fa fa-angle-left"></i> &nbsp; 权限体系之-21-passport springboot 整合 log4j2
            </a>
            

            
            <a class="next pull-right my-a" href="/2025/11/20/sso-31-passport-safe-security-xss" rel="bookmark">
              权限体系之-20-passport 安全之 XSS &nbsp; <i class="fa fa-angle-right"></i>
            </a>
            
          </div>
        </nav>
        <!--文章上下篇 END-->

      </div>
    </div>
  </div>

</article>
</div>

Vue 默认会自动转义。


2. 使用 DOMPurify(专业级过滤)

npm install dompurify
import DOMPurify from 'dompurify'

const safeHtml = DOMPurify.sanitize(dirtyHtml);

配合 v-html 才可安全使用。


3. 禁止使用 eval / new Function

任何动态 JS 字符串执行 = XSS 温床。


九、后端 Spring Boot 防御方案

1. 全局 XSS Filter(推荐)

@Component
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
    }
}

配合 Wrapper 过滤:

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        return HtmlUtils.htmlEscape(value);
    }
}

2. JSON 输出防护

配置 Jackson:

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.getFactory().setCharacterEscapes(new HtmlCharacterEscapes());
    return mapper;
}

十、浏览器层防护:CSP(最强防线)

HTTP 头:

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

Spring Boot 配置:

http.headers().contentSecurityPolicy(
    "default-src 'self'; script-src 'self'; object-src 'none';"
);

效果:

  • 禁止页面执行外部恶意脚本
  • 阻断内联脚本

十一、完整防御体系推荐

✅ 前端

  • 禁用 v-html
  • DOMPurify 清洗富文本
  • 路由参数统一 encode
  • 不拼接 HTML

✅ 后端

  • XSS Filter 全局过滤
  • Controller 参数校验
  • 默认 HTML escape

✅ 浏览器

  • CSP
  • HttpOnly Cookie
  • SameSite

十二、推荐的综合最佳实践

✅ 最安全组合

层级 防护
Vue 自动转义显示
API HTML Escape 处理
Header CSP 强制策略
Cookie HttpOnly + Secure

十三、简单总结(白话版)

XSS 就是别人把代码塞到你页面里,然后借你的系统攻击你的用户。

防御核心只有一句话:

✅ 不信任任何用户输入 ✅ 永远不要直接渲染未处理的内容 ✅ 所有输出必须经过转义或清洗


落地方案

明白,我给你整理一套 Spring Boot + Vue3 企业级防 XSS 攻击完整配置,覆盖前端、后端、浏览器策略,企业级可直接落地。我们按层级拆解:


一、前端 Vue3 防 XSS

1️⃣ 避免 v-html

❌ 错误写法:

<div v-html="userInput"></div>

✅ 安全写法:

<div></div>
  • Vue3 默认会自动对 `` 插值进行 HTML 转义。

2️⃣ 富文本或 HTML 内容需要安全处理

使用 DOMPurify 过滤用户输入的 HTML:

npm install dompurify
import DOMPurify from 'dompurify'

const safeHtml = DOMPurify.sanitize(dirtyHtml, {
  ALLOWED_TAGS: ['b','i','u','p','br','ul','li','a','img'],
  ALLOWED_ATTR: ['href','src','alt','title']
})

然后再渲染:

<div v-html="safeHtml"></div>

✅ 注意:

  • 不允许直接执行 JS(如 onerroronclick 等事件)
  • ALLOWED_TAGS/ATTR 可根据业务精简

3️⃣ URL 参数处理

const keyword = encodeURIComponent(route.query.keyword)
  • 防止反射型 XSS

4️⃣ 避免动态执行 JS

// 不安全
eval(userInput)
new Function(userInput)

二、后端 Spring Boot 防 XSS

1️⃣ 全局 XSS Filter

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.util.HtmlUtils;

import java.io.IOException;

@Component
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
    }
}

Wrapper 对用户输入统一转义

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.springframework.web.util.HtmlUtils;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        return value != null ? HtmlUtils.htmlEscape(value) : null;
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null) return null;
        for (int i = 0; i < values.length; i++) {
            values[i] = HtmlUtils.htmlEscape(values[i]);
        }
        return values;
    }

    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return value != null ? HtmlUtils.htmlEscape(value) : null;
    }
}

2️⃣ JSON 输出统一转义

import com.fasterxml.jackson.core.io.CharacterEscapes;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.getFactory().setCharacterEscapes(new HtmlCharacterEscapes());
        return mapper;
    }

    static class HtmlCharacterEscapes extends CharacterEscapes {
        private final int[] asciiEscapes;

        public HtmlCharacterEscapes() {
            asciiEscapes = standardAsciiEscapesForJSON();
            asciiEscapes['<'] = CharacterEscapes.ESCAPE_STANDARD;
            asciiEscapes['>'] = CharacterEscapes.ESCAPE_STANDARD;
            asciiEscapes['&'] = CharacterEscapes.ESCAPE_STANDARD;
            asciiEscapes['"'] = CharacterEscapes.ESCAPE_STANDARD;
            asciiEscapes['\''] = CharacterEscapes.ESCAPE_STANDARD;
        }

        @Override
        public int[] getEscapeCodesForAscii() {
            return asciiEscapes;
        }

        @Override
        public SerializableString getEscapeSequence(int ch) {
            return null;
        }
    }
}

✅ 这样返回给前端的 JSON 自动转义 <, >, ', " 等特殊字符,防止注入。


3️⃣ CSP(Content Security Policy)安全头

在 Spring Security 中设置:

http.headers()
    .contentSecurityPolicy("default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self' data:;")
    .and()
    .xssProtection(xss -> xss.block(true));
  • default-src 'self':默认只允许本域名资源
  • script-src 'self':禁止加载外部 JS
  • object-src 'none':禁止 Flash/插件执行
  • style-src 'self':只允许本地样式
  • img-src 'self' data::允许 base64 图片

response.setHeader("Set-Cookie", "SESSION=xxx; HttpOnly; Secure; SameSite=Strict");
  • 防止 XSS 偷 Cookie

三、前后端综合防护流程

  1. 前端:

    • 避免 v-html
    • 富文本过滤 DOMPurify
    • URL 参数 encode
    • 不动态执行 JS
  2. 后端:

    • XSS Filter 全局参数转义
    • JSON 输出转义
    • 富文本可用 Jsoup/HTML Sanitizer 做白名单过滤
  3. 浏览器:

    • CSP 强制策略
    • HttpOnly + Secure Cookie
    • SameSite Cookie

四、额外建议