1.什么是跨站点脚本(XSS)攻击?
跨站点脚本攻击,指攻击者在用户浏览网站时,将恶意的Javascript注入用户浏览器的行为。JavaScript可以读取或修改网页的任何部分,因此攻击者可以利用跨站点脚本漏洞进行很多操作。跨站点脚本是一种常见的攻击类型,下文将介绍2种常见的跨站点脚本攻击类型,并说明如何防范它们。
2.常见的2种跨站点脚本攻击类型
2.1 存储型跨站点脚本攻击
攻击者通过某些方式将JavaScript代码注入数据库,用户在浏览站点的特定页面时,将在浏览器端执行这些JavaScript代码。除了在前文juejin.cn/post/735287… 提到的SQL注入方式外,攻击者还可以通过其他途径插入恶意代码。例如,如果某个网站允许用户发表评论,那么该网站将把评论文本存储在数据库中,并将其显示给查看同一评论主题的其他用户。在这种情况下,攻击者执行跨站点脚本攻击的一种简单方法是将包含<script>标签的评论注入数据库。如果网站无法安全地构建HTML,那么每当页面呈现给其他用户时,<script>标签就会被写入HTML,并且JavaScript代码将在受害者的浏览器中执行。评论主题并不是唯一可以出现这类漏洞的地方。任何用户控制的内容都是需要保护的潜在攻击途径。攻击者可以通过将恶意脚本标签注入用户名、个人资料页面和在线评论中进行跨站点脚本攻击。
2.1.1 缓解措施:转义HTML字符
为了防止存储型的跨站点脚本攻击,需要转义来自数据存储的所有动态内容,以便浏览器将其视为HTML标签内容,而不是原始HTML。在浏览器中转义内容意味着用相应的实体编码替换HTML中的控制字符,如表1-1所示
| 字符 | 实体编码 |
|---|---|
| " | " |
| & | & |
| ' | ' |
| < | < |
| > | > |
在HTML中具有特殊含义的任何字符,例如<和>表示标签的开始和结束,都具有相应的安全实体编码。遇到实体编码时浏览器会将其识别为转义字符,并在视觉上将其呈现为相应的字符,最重要的是,不会将它们视为HTML标签。转义字符到未转义字符的转换发生在浏览器为页面构建DOM之后,因此浏览器不会执行<script>标签。以这种方式转义HTML控制字符将关闭大多数跨站点脚本攻击的大门。
2.1.2 缓解措施:实施内容安全策略
现代浏览器允许网站设置内容安全策略,通过在HTTP响应标头中设置内容安全策略,浏览器就不会执行内联的JavaScript代码。只有通过<script>标签中的src属性导入JavaScript时,浏览器才会在页面上执行JavaScript代码。典型的内容安全策略标头类似代码清单1-1
Content-Security-Policy: script-src 'self' https://apis.google.com
还可以在网页HTML的<head>元素的<meta>标签中设置站点的内容安全策略,如代码清单1-2
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://apis.google.com">
通过把浏览器需要从中加入脚本的域列入白名单,可以隐式地声明不允许使用内联JavaScript。在本例内容安全策略中,浏览器将仅从apis.google.com以及站点的任何域中加载JavaScript。要允许内联JavaScript,该策略必须包含关键字unsafe-inline。
2.2 反射型跨站点脚本攻击
数据库中的恶意JavaScript并不是跨站点脚本攻击的唯一载体。如果你的站点接受HTTP请求的一部分并将其显示在渲染的页面中,则呈现代码时需要防止通过HTTP请求注入恶意JavaScript。这种攻击为反射型跨站点脚本攻击。反射型跨站点脚本攻击的本质是:攻击者在http请求中发送恶意代码,然后服务器将其反射回来,比如搜索功能。反射型跨站点脚本攻击的常见目标区域是搜索页面和错误页面,因为它们通常将部分查询字符串回显给用户。
2.2.1 缓解措施:从HTTP请求转义动态内容
转义网站插入HTML页面的动态内容中的控制字符,可以有效地缓解反射型跨站点脚本漏洞。