什么是XSS攻击
XSS攻击是页面被注入了恶意代码,且恶意代码得以执行,从而产生的一系列后果。
通常页面中包含的用户输入内容都在固定的容器或者属性内,以文本的形式展示;
攻击者利用这些页面的用户输入片段,拼接特殊格式的字符串,突破原有的位置限制,形成代码片段;
攻击者通过在目标网站上注入脚本,使之在用户浏览器上运行,从而引发潜在风险;
通过HTML转义,可以防止XSS攻击。
可以通过哪些方式完成XSS攻击
在HTML中内嵌的文本中,恶意内容一scrip标签形式注入;
在内联的JavaScript中,拼接的数据突破了原本的限制(字符串,变量,方法名等);
在标签的
href、src等属性中,包含javascript:等可执行代码;在
onload、onerror、onclick等事件中,注入不受控制代码;在
style属性和标签中,包含类似background-image:url("javascript:...");的代码(新版本浏览器已经可以防范);在
style属性和标签中,包含类似expression(...)的CSS表达式代码(新版本浏览器已经可以防范)。
XSS攻击分类
储存型
步骤
攻击者将恶意代码提交到目标网站的数据库中;
用户打开目标网站时,网站服务器将恶意代码从数据库取出,拼接在HTML中返回给浏览器;
用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行;
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用模板网站的接口执行攻击者指定的操作。
反射型
步骤
攻击者构造出特殊的
URL,其中包含恶意代码;用户打开带有恶意代码的
URL时,网站服务端将恶意代码从URL中取出,拼接在HTML中返回给浏览器;用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行;
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用模板网站的接口执行攻击者指定的操作。
DOM型XSS
步骤
攻击者构造出特殊的
URL,其中包含恶意代码;用户打开带有恶意代码的
URL。用户浏览器接收到响应后解析执行,前端
JavaScript取出URL中的恶意代码并执行;恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用模板网站的接口执行攻击者指定的操作。
XSS 攻击的预防
XSS 攻击的两大要素
攻击者提交恶意代码;
浏览器执行恶意代码。
在用户输入阶段过滤掉用户的恶意代码能否有效的防御呢?
效果不大,原因有几点:
攻击者可以绕过前端输入,直接构造请求;
存入数据库前转义,输出的地方是不能被明确的,很容易造成页面乱码,或者
JavaScript报错。
当然,对于明确输出的内容还是可以进行过滤的,比如邮箱地址、URL、电话号码等。
过滤输入不可靠我们就通过防止浏览器执行恶意代码来防范XSS:
防止HTML中出现注入;
防止JavaScript执行时,执行恶意代码。
预防储存型和反射型XSS攻击
改成纯前端渲染,把代码和数据分隔开;
对HTML做充分的转义。
其它XSS防范措施
Content Security Policy
禁止加载外域代码,防止复杂的攻击逻辑;
禁止外域提交,网站被攻击后,用户的数据不会泄露到外域;
禁止内联脚本执行(规则较严格,目前发现GitHub使用);
禁止未授权的脚本执行(新特性,Google Map移动版在使用);
合理使用上报可以及时发现XSS,利于尽快修复问题。
输入内容长度控制
对于不信任的输入,控制其长度,虽然不能阻止攻击,但能增加攻击的难度。
其它
HTTP-only Cookie:禁止JavaScript读取某些敏感的Cookie,攻击者完成XSS注入后无法窃取此Cookie。
验证码:防止脚本冒充用户提交。