web 应用安全之 XSS 攻击
前言
在上一篇文章《web 应用安全之 SQL 注入》中,本人从 java 的角度就 Java web 开发过程中 SQL 注入的问题简单表达了下自己的观点,本文将在上一文的基础上继续讲述 web 应用安全的另一个问题 ————XSS 攻击。
什么是 XSS 攻击
XSS 攻击,全称是 “跨站点脚本攻击”(Cross Site Scripting),之所以缩写为 XSS,主要是为了和 “层叠样式表”(Cascading Style Sheets,CSS)区别开。恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。
XSS 攻击原理
- 攻击者对含有漏洞的服务器发起 XSS 攻击(注入 JS 代码);
- 诱使受害者打开受到攻击的服务器 URL;
- 受害者在 Web 浏览器中打开 URL,恶意脚本执行。
一个简单演示代码如下:
XSS 攻击的类型
常见的 XSS 攻击有三种:反射型、DOM-based 型、存储型。 其中反射型、DOM-based 型可以归类为非持久型 XSS 攻击,存储型归类为持久型 XSS 攻击。
反射型
DOM-based 型
1
2
3var content = document.getElementById("content");
var board = document.getElementById("board");
board.innerHTML = text.value; //发生DOM-based XSS攻击
存储型
XSS 的防御措施
编码
对用户输入的数据进行编码
HTML 编码
将不可信数据放入到 HTML 标签内(例如 div、span 等)的时候进行 HTML 编码
显示结果 | 描述 | 实体编号 |
---|---|---|
空格 |   ; | |
< | 小于 | < ; |
> | 大于 | > ; |
& | 和 | & ; |
‘’ | 引号 | " ; |
1 | function encodeForHTML(str, kwargs){ |
HTML Attribute 编码
将不可信数据放入 HTML 属性时(不含 src、href、style 和事件处理属性),进行 HTML Attribute 编码,除了字母数字字符以外,使用 HH;(或者可用的命名实体) 格式来转义 ASCII 值小于 256 所有的字符
1 | function encodeForHTMLAttibute(str, kwargs){ |
JavaScript 编码
将不可信数据放入事件处理属性、JavaScirpt 值时进行 JavaScript 编码,除字母数字字符外,使用 \xHH 格式转义 ASCII 码小于 256 的所有字符
1 | function encodeForJavascript(str, kwargs) { |
URL 编码
将不可信数据作为 URL 参数值时需要对参数进行 encodeURIComponent 编码
1 | function encodeForURL(str, kwargs){ |
CSS 编码
将不可信数据作为 CSS 时进行 CSS 编码,除了字母数字字符以外,使用 \XXXXXX 格式来转义 ASCII 值小于 256 的所有字符
1 | function encodeForCSS (attr, str, kwargs){ |
Http Only cookie
许多 XSS 攻击的目的就是为了获取用户的 cookie,将重要的 cookie 标记为 http only,这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie,这样就避免了 XSS 攻击利用 js 的 document.cookie 获取 cookie。
使用 XSS Filter
在上一篇文章《web 应用安全之 SQL 注入》中,讲 SQL 注入的防范与处理时,提到了自定义过滤规则防范 SQL 注入,同样的对于 XSS 我们也可以自定义过滤规则防范 XSS 攻击,我们只需要在重写 getParameter 方法中调用 XSS 的过滤规则即可,详情不在赘述。
附:2017 年公布了十大安全漏洞列表
- 注入
- 失效的身份认证
- 敏感信息泄漏
- XML 外部实体(XXE)
- 失效的访问控制
- 安全配置错误
- 跨站脚本(XSS)
- 不安全的反序列化
- 使用含有已知漏洞的组件
- 不足的日志记录和监控