如何解决 XSS 攻击





5.00/5 (6投票s)
在客户端和服务器端解决 XSS 攻击
引言
本文介绍了如何解决 XSS 攻击,请参阅我之前的文章,其中介绍了什么是 XSS 攻击。
服务器端可以做的事情
1. HttpOnly
只允许在 HTTP/HTTPS 协议下读取 Cookie,不允许 JavaScript 读取 Cookie。支持的浏览器有 Internet Explorer 6+、Firefox2+、Google、Safari4+。
将 HttpOnly 添加到 Cookie 中的 JavaEE 代码
response.setHeader("Set-Cookie","cookiename=value;
Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
附注:对于 HTTPS,我们还可以设置 Secure 字段来加密 cookie。这种方式实际上是禁止 JavaScript 读取 Cookie,这并不是预防措施。
2. 处理富文本
由于使用场景的问题,某些数据无法在服务器端加密。但富文本是完整的 HTML 代码,它不能在输出时放入属性中,因此您可以在服务器端处理它。处理方法是设置标签和属性的白名单,不允许它有特殊的标签或属性(例如 script, iframe, form 等),是的,这就是 XSS 过滤器。在存储数据之前过滤数据。
有一个名为 Anti-Samy 的 Java 开源项目,它是一个很好的 XSS 过滤器
Policy ploicy = Policy.getInstance(POLICY_FILE_LOCATION);
AntiSamy as = new AntiSamy();
CleanResults cr = as.scan(dirtyInput, policy);
MyUserDao.storeUserProfile(cr.getCleanHTML());
附注:当然,我们可以在客户端显示数据之前过滤数据,但我认为在服务器端进行此操作更好,只需要执行一次,并且可以为前端开发人员节省大量时间。
客户端可以做的事情
1. 输入检查
输入检查也需要在服务器端完成,因为用户可以轻松绕过 JavaScript 检查。目前,最流行的输入检查方法是在客户端进行 JavaScript 检查,并在服务器端进行相同的逻辑检查。JavaScript 输入检查可以防止大多数攻击,从而节省大量服务器资源。
简而言之,输入检查需要在客户端和服务器端都进行。
In addition, the places that attacker can input XSS, e.g.
1. all input boxes on page
2.window.location(href,hash,etc)
3.window.named
4.document.referrer
5.document.cookie
6.localstorage
7.XMLHttpRequest returned data
Of course, not limit these ways.
2. 输出检查
通常,当页面上输出参数时,对其进行编码或转义以防止 XSS 攻击。
XSS 攻击的本质是 HTML 注入,用户的输入被认为是 HTML 的一部分。因此,混淆了原始含义并产生了一个新的含义。
The places that can trigger XSS:
1.document.write
2.xxx.innerHTML=
3.xxx.outerHTML=
4.innerHTML.replace
5.document.attachEvent
6.window.attachEvent
7.document.location.replace
8.document.location.assign
如果使用 jQuery,那就是您使用 'append
', 'html
', 'before
', 'after
' 等的地方。大多数 MVC 框架都可以在其 View 层自动处理 XSS 问题。例如 AngularJS。
可以对输出进行编码的内容?
通常使用 HTMLEncode
和 JavaScriptEncode
,客户端和服务器端都可以这样做。
HTMLEncode
,即将string
转换为HTMLEntities
,通常转换这些字符(&?<?>?"?'?/)。JavaScriptEncode
,使用 '\' 来转换特殊字符。
在哪里需要进行编码?
- 在 HTML 标签中输出,属性中输出 -- 使用
HTMLEncode
- 在 JavaScript 的标签中输出 -- 使用
JavaScriptEncode
- 在事件中输出 -- 使用
JavaScriptEncode
。例如,<a href="#" onclick="funcA('$var')">test</a>
- 在 CSS 中输出 -- 使用与 JavaScript 类似的方式,将所有字符(字母和数字除外)编码为十六进制格式 "
\uHH
" - 在 URL 中输出 -- 通常,如果参数是完整的 URL 地址,则检查参数是否以 '
http
' 开头,如果不是,则添加 'http
' 以防止虚假协议 XSS 攻击,然后使用URLEncode
对该参数进行编码。
附注:URLEncode
可以将字符转换为 "%HH
" 格式。
摘要
前端开发人员必须知道在正确的位置使用正确的编码方法。有时,我们需要在一个地方同时使用 HTMLEncode
和 JavaScriptEncode
,而不仅仅是使用一种方法。