web安全 - XSS防御理念

要使XSS攻击成功,攻击者需要在网页中插入和执行恶意内容。web应用程序中的每个变量都需要受到保护,
确保所有变量都经过验证,然后被转义编码或者清理过滤,这就是完美的抗注入性。任何未经过此过程的
变量都是潜在的弱点。

框架使确保变量得到正确验证和转义或清理变得容易,然而框架往往并不完美,在React 和 Angular等流行
框架中仍然存在安全漏洞,输出编码和HTML清理有助于解决这些问题。

1. 输出编码

输出编码的目的是将不受信任的输入转换未安全的的形式,在这种形式中,输入作为数据显示给用户,而不
是在浏览器中作为代码执行。

  • 输出编码规则
编码类型 编码机制
HTML实体编码 & => &amp; < => &lt; > => &gt; " => &quot; ' => &#x27; / => &#x2F;
HTML属性编码 除字母数字字符外,使用HTML实体 &#xHH; 编码所有字符格式,包括空格。(HH = 十六进制)
URL编码 标准百分比编码,URL编码应该只用于编码参数值,而不是整个URL或路径片段
Javascript 编码 除字母数字字符外,使用\uXXXX unicode编码格式(X = 整数)对所有字符进行编码
CSS十六进制编码 CSS编码支持\XX 和\XXXXXX 两种格式,如果下一个字符继续编码序列,则两个字符的编码会出现问题。一种解决方案是在编码后添加一个空格, 第二种是建议使用全编码格式。
  • 在不同的上下文中进行安全编码
数据类型 上下文 代码示例 编码防御
字符串 HTML标签内 <span> Untrusted Data </span> HTML实体编码
字符串 安全的HTML属性 <input type="text" name="fname" value="Untrusted Data"> HTML属性编码
字符串 URL参数 <a href="/site/search?value=Untrused data"> clicke me</a> URL编码
字符串 href或者src属性中不可信的URL <a href="Untrusted Data" > click me <iframe src="Untrusted Data" /> 规范输入,URL验证,仅允许http 和https协议,进行属性编码
字符串 CSS值 <div style="width:Untrusted Data "> Selection </div> CSS十六进制编码
字符串 javascript 变量 <script> var currentValue='Untrusted Data';</script><script>someFunction('Untrusted Data');</script> 确保用引号包裹javascript变量,javascript十六进制编码,javascript unicode编码,避免反斜杠编码(', ")
HTML HTML标签内 <div> Untrusted HTML </div> HTML清理
字符串 Dom XSS <script>document.write("Untrusted Input: " + document.location.hash );</script> 使用安全的接收器,对不可信的数据根据上下文进行编码

2. HTML清理

有时用户需要编写HTML,一种情况是允许用户在所见即所得编辑器中更改内容的样式或结构。此处的输出
编码将防止XSS,但会破坏应用程序的预期功能,这时候应该使用HTML清理,它从变量中去除危险的HTML
并返回一个安全的HTML字符串。
注意:

  • 如果对内容清理后,再对其进行修改,则可能会使清理工作无效。
  • 如果对内容清理后,将其发送到库以供使用,则必须确保它不会以某种方式改变清理后的字符串,否则
    清理会变得无效。
  • 必须定期的修补正在使用的HTML清理库,比如DOMPurify。因为浏览器定期更改功能并发现被绕过。

3. 安全的接收器

安全专家讨论的源和接收器,如果你污染了一条河流,它就会流向下游某个地方。计算机安全也是如此,
XSS接收器就是将变量放入网页的地方,它们往往是DOM的一些API。安全的接收器将变量视为文本并且
永远也不会执行它。

下面是一些安全的接收器:

elem.textContent = dangerVariable;
elem.insertAdjacentText(dangerVariable);
elem.className = dangerVariable;
elem.setAttribute(safeName, dangerVariable);
formfield.value = dangerVariable;
document.createTextNode(dangerVariable);
document.createElement(dangerVariable);

使用不安全的接收器前对数据进行清理

elem.innerHTML = DOMPurify.sanitize(dangerVar); 

4. 其他安全措施

  • cookie 属性HttpOnly设置防止session cookie信息被客户端脚本读取
  • CSP 内容安全策略
  • WAF web应用防火墙
posted @ 2022-09-16 12:03  箫笛  阅读(66)  评论(0)    收藏  举报