一、概念
XSS(Cross Site Scripting)是跨站脚本攻击,即在他人站点嵌入带有攻击性的脚本。原本缩写应该是CSS,但为了与 Cascading Style Sheet(层叠样式表,也就是前端中样式CSS)区分,就将其缩写为 XSS。
二、特点
- XSS 攻击是通过网站暴露的用户输入框进行恶意代码植入的。
- XSS 攻击的源头是服务端过于信任客户端提交的数据,直接将数据存在服务器中。
三、示例
故事:黑客小黑常年从事秘密的网址攻击工作,这天小黑闲来无事,打开某论坛网站 A,在留言板的输入框中嵌入了恶意脚本,然后提交到服务器。老王有一天也访问了该网站,看到小黑的留言,出于好奇心点击了一下,结果弹出了本地存储的 cookie 信息。
分析:代码实现以上攻击过程。
- 网站留言板输入框如下
<textarea placeholder="请输入你的留言" value=""></textarea>
- 正常用户应该是输入自己的留言,但是小黑在输入框中输入了恶意脚本
<a href="javascript:alert(document.cookie)">点击这个链接,你将获得惊喜</a>
- 此时用户的留言字段 message 的值就是以上脚本,并且被提交到了服务器永久保存了下来。
- 当他人访问此网站,查看留言板页面时,该页面代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>留言板页面</title>
</head>
<body>
<div id="message"></div>
<!--此div用来显示从服务器获取的留言信息-->
</body>
<script>
var data =`<a href="javascript:alert(document.cookie)">`;
//该data理论上是从服务器调接口获取到的,这里直接模拟已经拿到的数据。
var message = document.getElementById('message');
message.innerHTML = data;
</script>
</html>
- 可以看到该页面包含了脚本信息
<a href="javascript:alert(document.cookie)">
,用户一旦点击,就会弹出本地保存的 cookie 信息。
总结:
XSS攻击发生的步骤如下:
- 攻击者在公开网站的输入框中嵌入恶意脚本;
- 该恶意脚本被作为值存储到服务器;
- 其他人访问该网站,网站会自动从服务器拉取恶意脚本并运行,或者诱导用户运行。
注意:执行脚本的核心代码是使用了 innerHTML 进行页面脚本填充,如果使用 textContent 就会将脚本转化为字符串。所以在 React 中不会出现以上情况,因为 React 的源码中是使用 textContent 来设置文本内容的。
React 代码如下:
<div id="example" ></div>
<script type="text/babel">
class App extends React.Component {
render() {
var content = `<a href='javascript:alert(document.cookie)'>点击</a>`;
return (
<div>{content}</div>
)
}
};
ReactDOM.render(<App/>, document.getElementById('example'));
</script>
界面显示如下:
React 源码内容:
var setTextContent = function (node, text) {
node.textContent = text;
};
四、攻击脚本标签
- a 标签
<a href=javascript:alert('xss')>点击有惊喜</a>
//这里单双引号,或者去掉引号均可;点击之后页面弹出'xss'。
- img 标签
<img src='#' onerror='alert(1)'/>
//打开嵌有本脚本的页面直接弹出'xss';
- iframe 标签
<iframe src=javascript:alert('xss')></iframe>
//打开嵌有本脚本的页面直接弹出'xss';
小结:
- a 标签通过 href 属性点击执行。
- img标签与iframe标签分别通过onerror方法和src属性直接执行。
- 任何标签都可以通过onmouseover、onclick等事件异步执行。
五、防范
理解了跨站脚本攻击之后,应该如何防范呢?
- 在所有需要进行提交的信息中,都进行模式匹配检查,一旦发现"javascript"关键字,就过滤掉。
- 对于用户提交的信息进行强校验,比如用户名,密码,URL、邮箱等信息进行符合规则的校验。
- 设置页面内容尽量使用 textContent 属性而不是 innerHTML属性。
六、其他
在前端领域中与 XSS 类似的还有 CSRF,想要了解的可以参考前端安全漏洞之 CSRF、前端安全漏洞 XSS 与 CSRF 异同。