文章目录
- XSS 漏洞的发生和修复
-
* 案例
- 注意特殊的 HTML 属性、JavaScript API
- 根据上下文采用不同的转义规则
XSS 漏洞的发生和修复
XSS 攻击是页面被注入了恶意的代码
案例
公司需要一个搜索页面,根据 URL 参数决定关键词的内容。小明写的前端页面代码如下:
<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>
您搜索的关键词是:<%= getParameter("keyword") %>
</div>
如果这个url是:http://xxx/search?keyword="><script>alert('XSS');</script>
,会导致页面弹出两次弹窗,因为当浏览器请求http://xxx/search?keyword="><script>alert('XSS');</script>
时,服务端会解析出请求参数keyword,得到"><script>alert('XSS');</script>
,拼接到HTML中返回给浏览器。形成了如下的
HTML:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
浏览器无法分辨出<script>alert('XSS');</script>
是恶意代码,因而将其执行。这里不仅仅div的内容被注入了,而且input的value属性也被注入,alert会弹出两次。
解决方案 :对特殊字符进行转义:
<input type="text" value="<%= escapeHTML(getParameter("keyword")) %>">
<button>搜索</button>
<div>
您搜索的关键词是:<%= escapeHTML(getParameter("keyword")) %>
</div>
上述url(http://xxx/search?keyword="><script>alert('XSS');</script>
)展示的内容如下:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
总结:
- 通常页面中包含的用户输入内容都在固定的容器或者属性内,以文本的形式展示。
- 攻击者利用这些页面的用户输入片段,拼接特殊格式的字符串,突破原有位置的限制,形成了代码片段。
- 攻击者通过在目标网站上注入脚本,使之在用户的浏览器上运行,从而引发潜在风险。
- 通过 HTML 转义,可以防止 XSS 攻击
注意特殊的 HTML 属性、JavaScript API
如果要根据URL参数决定跳转路径,前端代码:<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳转...</a>
,假如URL
为http://xxx/?redirect_to=javascript:alert('XSS')
,服务端响应就成了:<a href="javascript:alert('XSS')">跳转...</a>
,虽然代码不会立即执行,但一旦用户点击a标签时,浏览器会就会弹出“XSS”。
解决方案 :先把getParameter("redirect_to")
的值转换成小写,再比对,下文省略了转换成小写的代码
// 禁止 URL 以 "javascript:" 开头
xss = getParameter("redirect_to").startsWith('javascript:');
if (!xss) {
<a href="<%= escapeHTML(getParameter("redirect_to"))%>">
跳转...
</a>
} else {
<a href="/404">
跳转...
</a>
}
如果链接是http://xxx/?redirect_to=%20javascript:alert('XSS')
,%20javascript:alert('XSS')
经过URL解析后变成javascript:alert('XSS')
,这个字符串以空格开头。这样攻击者可以绕过后端的关键词规则,又成功的完成了注入。最终,小明选择了白名单的方法,彻底解决了这个漏洞:
// 根据项目情况进行过滤,禁止掉 "javascript:" 链接、非法 scheme 等
allowSchemes = ["http", "https"];
valid = isValid(getParameter("redirect_to"), allowSchemes);
if (valid) {
<a href="<%= escapeHTML(getParameter("redirect_to"))%>">
跳转...
</a>
} else {
<a href="/404">
跳转...
</a>
}
总结:
- 做了 HTML 转义,并不等于高枕无忧。
- 对于链接跳转,如
<a href="xxx"
或location.href="xxx"
,要检验其内容,禁止以javascript:
开头的链接,和其他非法的scheme。
根据上下文采用不同的转义规则
网络安全工程师(白帽子)企业级学习路线
第一阶段:安全基础(入门)
第二阶段:Web渗透(初级网安工程师)
第三阶段:进阶部分(中级网络安全工程师)
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!