TL;DR:所有写得好的网站(/应用程序)都必须发出头部X-XSS-Protection: 0,忘记这个功能吧。如果您希望拥有更好的用户代理能够提供的额外安全性,请使用严格的Content-Security-Policy报头。
长一点的回答:
HTTP报头X-XSS-Protection是微软在Internet Explorer 8.0 (MSIE 8)中引入的功能之一,旨在提高错误书写网站的安全性。
其思想是应用某种启发式方法来检测反射XSS攻击并自动消除攻击。
有问题的部分是“启发式”和“绝育”。启发式会导致误报和绝杀不能安全地完成,因为它会导致副作用,可以用于在完全安全的网站上实现XSS攻击和侧通道数据攻击。
不好的部分是,如果一个网站没有发出X-XSS-Protection头,那么浏览器就会表现得好像发出了X-XSS-Protection: 1头。最糟糕的是,这个值是这个头的所有可能值中最不安全的值!
对于一个给定的安全网站(也就是说,该网站没有反映XSS漏洞),这种“XSS保护”特性允许以下攻击:
X-XSS-Protection: 1 allows attacker to selectively block parts of JavaScript and keep rest of the scripts running. This is possible because the heuristics of this feature are simply "if value of any GET parameter is found in the scripting part of the page source, the script will be automatically modified in user agent dependant way". In practice, the attacker can e.g. add query parameter ?disablexss=<script%20src="framebuster.js" and the browser will automatically remove the string <script src="framebuster.js" from the actual page source. Note that the rest of the page continues execute JavaScript and the attacker just selectively removed this part of page security. In practice, any JS in the page source can be modified. For some cases, a page without XSS vulnerability having reflected content can be used to run selected JavaScript on page due the neutering incorrectly turning plain text data into executable JavaScript code. (That is, turn textual data within a normal DOM text node into content of <script> tag and execute it!)
X-XSS-Protection: 1; mode=block allows attacker to leak data from the page source by using the behavior of the page as a side-channel. For example, if the page contains JavaScript code along the lines of var csrf_secret="521231347843", the attacker simply adds an extra parameter e.g. leak=var%20csrf_secret="3 and if the page is NOT blocked, the 3 was incorrect first digit. The attacker tries again, this time leak=var%20csrf_secret="5 and the page loading will be aborted. This allows the attacker to know that the first digit of the secret is 5. The attacker then continues to guess the next digit. This allows easily brute-forcing of CSRF secrets one digit at a time or any other secret value in the <script> source.
In the end, if your site is full of XSS reflection attacks, using the default value of 1 will reduce the attack surface a little bit. However, if your site is secure and you don't emit X-XSS-Protection: 0, your site will be vulnerable with any browser that supports this feature. If you want defense in depth support from browsers against yet-unknown XSS vulnerabilities on your site, use a strict Content-Security-Policy header and keep sending 0 for this mis-feature. That doesn't open your site to any known vulnerabilities.
目前该功能在MSIE, Safari和谷歌Chrome默认启用。这曾经在Edge中启用,但微软已经从Edge中删除了这一错误功能。Mozilla Firefox从未实现此功能。
参见:
https://homakov.blogspot.com/2013/02/hacking-facebook-with-oauth2-and-chrome.html
https://blog.innerht.ml/the-misunderstood-x-xss-protection/
http://p42.us/ie8xss/Abusing_IE8s_XSS_Filters.pdf
https://www.slideshare.net/masatokinugawa/xxn-en
https://bugs.chromium.org/p/chromium/issues/detail?id=396544
https://bugs.chromium.org/p/chromium/issues/detail?id=498982