🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## **一、什么是 XSS ?** XSS (Cross Site Scripting),即跨站脚本攻击,是一种常见于 Web 应用中的计算机安全漏洞。恶意攻击者往 Web 页面里嵌入恶意的客户端脚本,当用户浏览此网页时,脚本就会在用户的浏览器上执行,进而达到攻击者的目的。比如获取用户的 Cookie、导航到恶意网站、携带木马等。借助安全圈里面非常有名的一句话: ~~~text 所有的输入都是有害的。 ~~~ 这句话把 XSS 漏洞的本质体现的淋漓尽致。大部分的 XSS 漏洞都是由于没有处理好用户的输入,导致恶意脚本在浏览器中执行。任何输入提交数据的地方都有可能存在 XSS。 ## **二、XSS 攻击分类** 第一种:反射型 第二种:持久型 第三种:DOM 型( DOM Based XSS ) ## **三、XSS 防御** **1、使用 XSS Filter** 针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容。比如: 表单数据指定值的类型:年龄只能是 int 、name 只能是字母数字等。 过滤或移除特殊的 html 标签:\<script\>、\<iframe\>等。 过滤 js 事件的标签:onclick、onerror、onfocus等。 **2、html 实体** 当需要往 HTML 标签之间插入不可信数据的时候,首先要做的就是对不可信数据进行 HTML Entity 编码, 在 html 中有些字符对于 HTML 来说是具有特殊意义的,所以这些特殊字符不允许在文本中直接使用,需要使用实体字符。 html 实体的存在是导致 XSS 漏洞的主要愿意之一,因此我们需要将实体转化为相应的实体编号。 **3、JavaScript编码** 这条原则主要针对动态生成的JavaScript代码,这包括脚本部分以及HTML标签的事件处理属性(如onerror, onload等)。 在往JavaScript代码里插入数据的时候,只有一种情况是安全的,那就是对不可信数据进行JavaScript编码, 并且只把这些数据放到使用引号包围起来的值部分(data value)之中,除了上面的那些转义之外,还要附加上下面的转义: \ 转成 \\ / 转成 \/ ; 转成 ;(全角;) 注意:在对不可信数据做编码的时候,不能图方便使用反斜杠\ 对特殊字符进行简单转义,比如将双引号 ”转义成 \”, 这样做是不可靠的,因为浏览器在对页面做解析的时候,会先进行HTML解析,然后才是JavaScript解析, 所以双引号很可能会被当做HTML字符进行HTML解析,这时双引号就可以突破代码的值部分,使得攻击者可以继续进行XSS攻击; 另外,输出的变量的时候,变量值必须在引号内部,避免安全问题;更加严格的方式,对除了数字和字母以外的所有字符, 使用十六进制\xhh 的方式进行编码。 **4、Http Only cookie** 许多 XSS 攻击的目的就是为了获取用户的 cookie,将重要的 cookie 标记为 http only, 这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie, 这样就避免了 XSS 攻击利用 js 的 document.cookie获取 cookie。 HttpOnly是cookie里面一个属性,假如在cookie里面设置了HttpOnly这个属性,那么JavaScript将无法访问到我们到cookie, 但是这个方法也只能是防御cookie劫持。HttpOnly设置规则如下。 ``` <?php     header("set-cookie: username=admin");     header("set-cookie: password=123456;httponly",false); ?> ``` **5、X-Frame-Options配置:** 低危漏洞- X-Frame-Options Header未配置X-Frame-Options 响应头 X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 \<frame\>, \</iframe\> 或者 \<object\> 中展现的标记。 网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。 使用 X-Frame-Options &nbsp; X-Frame-Options 有三个值: **&emsp;&emsp;DENY** &emsp;&emsp;表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。 **&emsp;&emsp;SAMEORIGIN** &emsp;&emsp;表示该页面可以在相同域名页面的 frame 中展示。 **&emsp;&emsp;ALLOW-FROM uri** &emsp;&emsp;表示该页面可以在指定来源的 frame 中展示。 &emsp;&emsp;换一句话说,如果设置为 DENY,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为 SAMEORIGIN,那么页面就可以在同域名页面的 frame 中嵌套。 &nbsp; **配置代理服务器**: **&emsp;&emsp;配置 Apache** &emsp;&emsp;在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 ‘site’ 的配置中: ``` Header always append X-Frame-Options SAMEORIGIN ``` **&emsp;&emsp;配置 nginx** &emsp;&emsp;配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 ‘http’, ‘server’ 或者 ‘location’ 的配置中: ``` add_header X-Frame-Options SAMEORIGIN; ``` **&emsp;&emsp;配置 IIS** &emsp;&emsp;配置 IIS 发送 X-Frame-Options 响应头,添加下面的配置到 Web.config 文件中: ``` <system.webServer> ... <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> </customHeaders> </httpProtocol> ... </system.webServer> ``` &nbsp; **总结:** 对输入输出做严格的过滤、添加HttpOnly、X-Frame-Options配置