什么是 XSS(跨站脚本攻击)?

XSS(Cross-Site Scripting)是一种常见的安全漏洞,攻击者通过在页面中注入恶意脚本代码,诱导用户的浏览器执行这些代码,从而达到窃取用户数据、伪造操作或劫持用户会话的目的。

XSS 的攻击目标通常是用户的浏览器,而不是服务器本身。


XSS 分类

  1. 存储型 XSS

    • 恶意脚本被永久存储在服务器上(如数据库中)。
    • 用户访问包含恶意脚本的页面时,脚本被加载并执行。
    • 示例: 攻击者在留言板中输入:
      <script>alert('Your session is hijacked!');</script>
      
      如果网站没有对用户输入进行过滤,其他用户访问留言板时会触发这个脚本。
  2. 反射型 XSS

    • 恶意脚本通过 URL 参数或其他途径传递,服务器直接将其返回到页面中。
    • 用户点击带有恶意脚本的链接时,脚本被执行。
    • 示例: 用户访问这样的链接:
      http://example.com?query=<script>alert('Hacked');</script>
      
      如果服务器直接将 query 参数渲染到页面中,脚本会执行。
  3. DOM 型 XSS

    • 恶意脚本通过浏览器端的 JavaScript 操作直接注入,不经过服务器。
    • 示例: 如果网站的某个功能是从 URL 中读取参数并插入到 DOM 中,而没有过滤:
      document.body.innerHTML = "Welcome, " + location.search.substring(1);
      
      当用户访问 http://example.com/?<script>alert('XSS');</script> 时,恶意代码会直接被执行。

XSS 的危害

  • 窃取用户的登录信息(如 Cookies 和 Session Token)。
  • 劫持用户会话(冒充用户进行操作)。
  • 在页面中加载恶意内容(如钓鱼网站、广告等)。
  • 操作用户的浏览器(如重定向到恶意网站)。

XSS 的防范措施

1. 输入过滤
  • 对用户的输入进行严格过滤和验证。
  • 禁止用户输入 HTML、JavaScript 等脚本内容。
  • 示例: 使用 正则表达式 或专用库过滤用户输入:
    const sanitizeInput = (input) => input.replace(/<[^>]+>/g, "");
    

2. 输出编码
  • 在将用户输入的内容输出到页面之前,对内容进行编码。
  • 确保 HTML 特殊字符(如 <, >, ", ' 等)不会被解释为 HTML。
  • 示例: 使用框架自带的转义工具:
    {{ userInput }}
    
    Vue 和 React 等现代前端框架默认会对动态内容进行 HTML 编码。

3. Content Security Policy (CSP)
  • 设置 CSP 限制页面中允许加载的资源。
  • 禁止页面加载外部的 JavaScript 文件或执行内联脚本。
  • 示例(设置 HTTP 响应头):
    Content-Security-Policy: script-src 'self'
    
    这会阻止外部脚本的执行。

4. 避免使用危险的 DOM 操作
  • 避免直接插入 HTML 到页面中。
  • 不安全的代码
    document.body.innerHTML = userInput;
    
  • 安全的代码: 使用安全的 DOM API,比如:
    const div = document.createElement("div");
    div.textContent = userInput;
    document.body.appendChild(div);
    

5. 使用框架的安全特性
  • 使用现代框架(如 Vue、React、Angular),它们默认会对动态内容进行 HTML 转义。
  • 在 Vue 中,默认情况下:
    <p>{{ userInput }}</p>
    
    会将 userInput 中的 <script> 转义为普通字符串。

6. HTTP-Only 和 Secure Cookie
  • 避免将敏感信息存储在客户端可访问的地方(如 localStoragesessionStorage)。
  • 将 token 或 session ID 存储在 HttpOnly 的 Cookie 中,这样 JavaScript 无法读取它。
  • 示例(后端设置 Cookie):
    Set-Cookie: token=abc123; HttpOnly; Secure
    

7. 验证用户输入
  • 检查输入的格式和内容是否符合预期。
  • 例如,用户名只能包含字母和数字:
    const isValidUsername = (input) => /^[a-zA-Z0-9]+$/.test(input);
    

8. 使用专用库
  • 使用可靠的第三方库处理用户输入或 HTML 内容。
  • 示例库:
    • DOMPurify:清理用户输入的 HTML,防止 XSS。
      import DOMPurify from "dompurify";
      const cleanHtml = DOMPurify.sanitize(userInput);
      

9. 设置 SameSite Cookie
  • 限制 Cookie 的跨站点发送,防止被用于跨站请求伪造(CSRF)攻击。
  • 示例:
    Set-Cookie: sessionId=abc123; SameSite=Strict;
    

总结

优先事项
  1. 对用户输入 过滤转义
  2. 避免直接操作 HTML,优先使用框架的模板引擎。
  3. 使用安全的存储方式(如 HttpOnly Cookie)管理 token。
  4. 设置 CSP 限制脚本执行来源。
  5. 检查后端是否也对用户数据进行了验证,前后端共同防范。

如果你想了解具体实现的代码或者更多示例,我可以进一步说明!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值