[网络安全] 如何预防XSS

打印 上一主题 下一主题

主题 1011|帖子 1011|积分 3033

XSS (Cross-Site Scripting,跨站脚本攻击) 是一种代码注入攻击。攻击者通过在目标网站注入恶意脚本,使其在用户浏览器中执行,从而窃取用户敏感信息如 Cookie 和 SessionID。
CSS 在前端已经被用了,为了避免歧义用了 XSS 作为缩写。
XSS 的本质是恶意代码与网站正常代码混在一起,浏览器无法分辨它们的可信度,终极导致恶意代码被执行。
XSS的危害

浏览器无法区分恶意代码和正常代码,它们拥有雷同的权限。恶意代码可以读取用户的敏感数据,比如 cookie 和 sessionID 等等。
可能的危害如下:

  • 由于恶意代码可以获取cookie和sessionID等数据,它可以获取用户的隐私数据并发送到攻击者的服务器举行网络;
  • 恶意代码以用户(被攻击者)的名义,构造带有恶意代码的 URL 举行传播。
XSS的分类

根据攻击者注入恶意脚本的方式的差别,XSS 可以被分为三类:
存储型 XSS


  • 存储区:后端数据库
  • 插入点:HTML
  • 攻击步调

    • 攻击者将恶意代码提交到目标网站的数据库。
    • 用户打开目标网站时,恶意代码从数据库取出并嵌入 HTML。
    • 用户浏览器执行恶意代码,导致用户数据被窃取或伪造操作被执行。

  • 特点:恒久性长,危害性大
    以 POST 评论和 GET 评论为例,攻击者只要发布一条带有恶意脚本的评论,这个攻击就可能影响到全部浏览到这一条评论的别的用户。并且这条评论是存储在数据库里的,假如没有对用户提交的评论做过滤,那么这个恶意的攻击会一直存储在数据库里直到有用户浏览到它,因此说它是恒久的。
    下图中的步调 1 和步调 2 之间可能隔断很久。

案例
假如用户发布了一条带有恶意代码的评论,这条评论被存储到了数据库里。
  1. {
  2.     "comment": ""
  3. }
复制代码
如果网站利用服务端渲染,那么在服务端会发生模板的数据填充:
  1.   用户评论:<%= comment %>
复制代码
终极前端拿到的 HTML 是:
  1.   用户评论:<%= comment %>
复制代码
恶意脚本将被执行。
客户端渲染在利用innerHTML的时候也要十分注意。
反射型 XSS


  • 插入点:HTML
  • 攻击步调

    • 攻击者构造一个带有恶意代码的 URL。
    • 用户打开该 URL 时,网站从 URL 中提取恶意代码并插入 HTML。
    • 用户浏览器执行恶意代码,导致数据走漏或伪造操作。

  • 特点:反射型的特点是必须用户点击这个经过恶意构造的URL才会被攻击,并且脚本显现在URL上,相对来说比较容易被发现。反射型XSS有经过后端。
案例
一个搜刮页面,搜刮的 query 通过 url 带参。

  • php代码:
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4.     <meta charset="UTF-8">
    5.     <title>搜索结果</title>
    6. </head>
    7. <body>
    8.     <h1>搜索结果</h1>
    9.    
    10.         你搜索了: <?php echo $_GET['q']; ?>
    11.    
    12. </body>
    13. </html>
    复制代码
  • 攻击示例:
    攻击者可以构造一个携带恶意脚本的URL:
    1. http://example.com/search.html?q=
    复制代码
    用户点击该链接后,服务器会直接将 q 参数的值插入到页面中,天生的页面 HTML 如下:
    1.     你搜素了:
    复制代码
    浏览器解析并执行了 script 标签内的内容,从而触发了 XSS 攻击。
DOM 型 XSS


  • 插入点:前端 JavaScript
  • 攻击步调

    • 攻击者构造一个特别的 URL。
    • 用户打开该 URL 后,前端 JavaScript 处理时会执行恶意代码。
    • 恶意代码在浏览器中运行,可能导致数据走漏或伪造操作。

  • 特点:DOM 型 XSS 仅发生在前端。
案例
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>搜索结果</title>
  6. </head>
  7. <body>
  8.     <h1>搜索结果</h1>
  9.    
  10.         正在搜索:
  11.    
  12.    
  13. </body>
  14. </html>
复制代码
攻击者可以构造一个包罗恶意代码的链接:
  1. http://example.com/search.html?q=
复制代码
当链接被访问时,恶意脚本就会被插入到界面中并执行:
  1. document.getElementById('search-query').innerHTML = "";
复制代码
XSS的预防

XSS 有两大要素,一是攻击者提交恶意代码,二是浏览器执行恶意代码。
转义用户输入(不实用)

为了预防攻击者提交恶意代码,可以考虑对用户的输入举行过滤。
利用合适的转义函数,例如 escapeHTML(),将用户输入的特别字符转换为安全的 HTML 实体。
  1. function escapeHTML(str) {
  2.   return str.replace(/&/g, "&")
  3.             .replace(/</g, "<")
  4.             .replace(/>/g, ">")
  5.             .replace(/"/g, """)
  6.             .replace(/'/g, "&#x27;")
  7.             .replace(/\//g, "/");
  8. }
复制代码
这种方法只能用于一些简单的场景。它的缺点在于:

  • 如果这个转义仅发生在前端提交请求之前,攻击者仍可以手动构造请求。
  • 如果这个转义发生在后端将数据写入数据库之前,也是不合理的,因为我们不知道这个数据将来应用的环境是哪里。上面这段代码的转义只能应用于浏览器环境的HTML里,转义后的数据无法在桌面客户端、安卓端等等别的环境上正常显示。
总结:

  • 转义用户输入只能应用于简单的场景;
  • 转义最好应用在Web前端渲染数据时,而不是用户提交数据时;
  • 对于明确的类型,比如数字、电话、URL、邮箱等数据,做一下数据过滤还是很有必要的。
用户输入环节并不能很好地预防 XSS,预防 XSS 的主要工作集中在预防浏览器执行恶意代码上。
关于这一点又有两类操作:

  • 防止 HTML 被注入;
  • 防止 JavaScript 执行恶意代码。
预防反射型和存储型

这两种类型都是在后端服务器上完成模板拼接的过程中,将恶意代码嵌入到了 HTML  中。
两种解决方法分别是:客户端渲染、转义HTML。
纯客户端渲染

纯客户端渲染:客户端访问页面,服务端返回的页面不带有任何业务数据,由前端的 JavaScript 通过 AJAX 异步请求数据后举行填充。
纯客户端渲染可以通过 .innerText,.setAttribute,.style等 API 来插入后端返回的业务内容(这些内容可能存在恶意代码),通过这种方式插入的内容不会被浏览器当成代码执行。
局限

  • 纯客户端渲染仍要注意 DOM型 XSS 攻击。
  • 部门页面临于性能有较高需求,或者需要考虑SEO,仍需要服务端渲染。
转义 HTML

对于服务端渲染,在拼接带有业务数据的 HTML 时,要对 HTML 的各个插入点举行充分的转义。
一些模板引擎可能仅对 & < > " ' / 举行转义,这实在是远远不够的,插入点有很多种,包罗但不限于:
<ul>在 HTML 内嵌的文本中,以 script 标签的情势注入;
在内联的 javascript 中,拼接的数据突破了原本的限定(字符串、方法名等等);
例如,a 标签的 href 可能理想状态下是插入一个路径链接,如果这个 href 插入的字符串是一个 javascript:恶意代码的情势,当 a 标签被点击时,恶意代码就会被执行。
对于标签的属性,如果注入的值包罗双引号,就会导致这个属性的值提前结束,从而可以注入别的属性或者标签;
例如:
注入别的属性示例
  1. // src 是用用户数据拼接的
  2. <img src="https://www.cnblogs.com/<%= imgSrc %>" />
  3. // 如果用户数据如下
  4. $imgSrc = 'https://www.cnblogs.com/./not-exist-img.png" onerror="javascript:恶意代码'
  5. // 那么拼接后的 img 标签就是
  6. <img src="https://www.cnblogs.com/./not-exist-img.png" onerror="javascript:恶意代码" />
复制代码
图片加载不到,会触发 onerror 中的恶意代码。
注入别的标签示例
  1. <img src="https://www.cnblogs.com/<%= imgSrc %>" />
复制代码
如果 imgSrc 插入的内容是 " />

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

飞不高

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表