恶意脚本如何拦截过滤

wen 开源项目 30

本文目录导读:

恶意脚本如何拦截过滤

  1. 后端防御(根源过滤,最有效)
  2. 前端防御(浏览器端加固)
  3. 特定恶意脚本的拦截场景
  4. 总结与最佳实践清单

恶意脚本的拦截和过滤是网络安全的重要环节,由于恶意脚本(如XSS攻击、恶意重定向、挖矿脚本等)通常通过浏览器执行,因此防御策略主要集中在输入过滤输出编码安全配置上。

以下是从不同层面进行拦截与过滤的方法,分为前端防御(浏览器端)和后端防御(服务器端),以及一些通用工具。

后端防御(根源过滤,最有效)

后端是防御的第一道防线,因为所有输入最终都会到达服务器,核心原则是:永远不要信任用户的输入

严格的输入验证与过滤

  • 白名单策略: 只允许特定格式的字符通过(只允许字母、数字、少数标点),拒绝所有其他字符。
  • 黑名单过滤(不推荐单独使用): 过滤 <script>, onerror, javascript: 等关键词,但很容易被绕过(如使用 \<script\><SCRIPt><img src=x onerror=alert(1)>)。
  • 过滤特殊字符:<, >, , , & 进行转义或删除。

输出编码(关键步骤)

即使输入过滤了,有时数据来自数据库(可能存了恶意内容)。在将数据输出到HTML、JavaScript、CSS或URL中时,必须进行编码。

  • HTML实体编码: 针对HTML上下文。
    • < 编码为 &lt;
    • > 编码为 &gt;
    • 将 编码为 &quot;
    • & 编码为 &amp;
  • JavaScript编码: 当数据直接放入 <script> 标签或事件监听器中时,使用 \x\u 编码。
  • URL编码: 使用 encodeURIComponent
  • CSS编码: 避免使用 expression() 等危险函数。

使用安全的框架和API

  • 现代Web框架(如React, Vue, Angular): 默认已经实现了输出编码,在JSX中直接渲染变量 {userInput} 会自动转义HTML。
  • 后端模板引擎: 如Thymeleaf(Java)、Jinja2(Python)、Blade(PHP),它们默认启用了上下文感知的转义。

内容安全策略(CSP,Content-Security Policy)

CSP是后端通过HTTP响应头告诉浏览器允许加载哪些资源的规则,是阻止恶意脚本执行的终极防线。

  • 方法: 在服务器响应头中添加:
    Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;
  • 作用:
    • 禁止内联脚本: script-src 'self' 会拒绝所有内嵌在HTML中的 <script>alert(1)</script>,只允许加载同源的外部JS文件。
    • 禁止eval() script-src 'none' 之类能有效阻止动态执行。
    • 限制来源: 只允许从你信任的CDN加载库。
    • 报告模式: 配合 report-uri 可以监控到哪些脚本被拦截了。

前端防御(浏览器端加固)

前端防御通常是辅助手段,因为攻击者可能直接绕过前端(例如用curl请求),但它能提升用户体验和防止一些非持久性攻击。

输入限制

  • MaxLength属性: 限制输入字段长度(虽然不能防止脚本,但能减少攻击面)。
  • 正则验证: 在表单提交前,用JavaScript验证字段只包含预期格式(如邮箱、数字)。注意:这不能代替后端验证。

内容安全策略(CSP)的前端实现

虽然CSP通常由后端设置,但也可以在前端通过<meta>标签实现(但优先级低于HTTP头)。

<meta http-equiv="Content-Security-Policy" content="default-src 'self';">

处理动态内容

  • 使用textContent而不是innerHTML 设置纯文本时,textContent 会自动转义HTML标签,不会执行脚本。
  • innerHTML 的安全使用: 如果必须使用 innerHTML,一定要对插入的字符串进行HTML实体编码(如使用 DOMPurify 库)。
  • 避免使用eval() 不要使用 eval()setTimeout(string)new Function(string) 等动态执行代码的函数。

使用安全库

  • DOMPurify: 这是一个非常流行的前端库,专门用于清理HTML,只允许安全的标签和属性,同时阻止XSS。
    var clean = DOMPurify.sanitize(dirtyHtml);
    document.getElementById('output').innerHTML = clean;

使用子资源完整性(SRI)

加载第三方CDN的库时,使用 integrity 属性确保文件没有被篡改。

<script src="https://cdn.example.com/script.js" 
        integrity="sha384-...哈希值..." 
        crossorigin="anonymous">
</script>

特定恶意脚本的拦截场景

挖矿脚本(Coinhive等)

  • CSP控制: 限制 connect-srcscript-src,只允许白名单域名。
  • 浏览器插件: 如uBlock Origin、NoCoin。
  • 监控: 服务器端监控CPU占用率异常。

恶意重定向

  • 验证URL来源: 后端对 location.href 的目标进行白名单校验。
  • 检查Referrer Header: 用户流量是否来自第三方来源。

键盘记录/盗取Cookie

  • HttpOnly Cookie: 设置Cookie为 HttpOnly=true,这样JavaScript无法通过 document.cookie 读取。这是防止XSS盗取Cookie最有效的方法。
  • SameSite 属性: 设置 SameSite=StrictLax,防止CSRF和部分XSS攻击。

总结与最佳实践清单

  1. 绝对不要信任用户输入(后端白名单验证)。
  2. 输出时始终编码(根据上下文选择编码方式)。
  3. 启用并严格执行内容安全策略(CSP)(从 script-src 'self' 开始,逐步收紧)。
  4. 给所有Cookie设置 HttpOnlySecure 属性(除非确实需要JavaScript读取)。
  5. 使用安全的框架(React/Vue)并遵循其安全指南(避免使用v-htmldangerouslySetInnerHTML直接插入用户内容)。
  6. 如果必须插入用户提供的HTML(如富文本编辑器),使用经过广泛验证的清理库(如DOMPurify、OWASP Java HTML Sanitizer、bleach(Python))。
  7. 定期更新依赖(库和框架的漏洞修复很重要)。
  8. 使用工具扫描(如OWASP ZAP、Burp Suite、或在线XSS扫描器)。

核心一句话:后端输入过滤 + 上下文输出编码 + 严格CSP + HttpOnly Cookie = 拦截95%以上的恶意脚本。

抱歉,评论功能暂时关闭!