除了Firefox之外,所有浏览器都禁止对EJS页面进行XSS攻击

时间:2016-11-19 08:44:41

标签: javascript security firefox xss

我正在使用这个非常简单的测试用例在浏览器上测试XSS:

  1. 该页面在Express + EJS上运行
  2. 在routes / index.js上,我设置以下内容以获取关键字查询字符串值:
  3. app.get('/search', function(req, res) { res.render('../views/pages/index', { title: req.query.keyword }); });

    1. 然后index.ejs页面获取title变量并将其呈现为:<h1><%- title %></h1>(注意我转义标题变量。)
    2. 当我复制以下网址(http://localhost:3001/search?keyword=%3Cimg%20src%3D%22private%2Fdist%2Flogo.png%22%20onerror%3D%22window.location%3D%27http%3A%2F%2Fgoogle.com%27%22%20%2F%3E)时,有趣的是我测试的每个浏览器(Chrome,Opera,Safari,IE8),但Firefox会发出警告,说他们拒绝执行脚本。
    3. 所以我想问题是,如果开发人员在这种情况下意外地无法逃脱字符串,并且除了Firefox之外的所有浏览器都抓住了这个,那么Firefox在执行XSS审核时遇到了问题?我是正确的假设吗?

      另外,我是否正确地认为作为开发人员,我们应该总是转义从URL或服务器传递的值?

      提前感谢您的建议,如果我问愚蠢的问题,请原谅我 - 刚刚开始了解这个XSS的事情。

1 个答案:

答案 0 :(得分:1)

当然这不是一个愚蠢的问题,它是一个非常有效的问题。让我试着解决一些问题。

XSS的解决方案是输出编码。这意味着在根据写入的上下文将变量写入页面时编码特殊字符。对于html上下文(html标签之间的文本,甚至是引号之间的标签属性值),它是html编码,但对于Javascript上下文(在html中的脚本标签之间或在onclick等事件属性中编写变量时),它必须是Javascript (字符串)编码。

所有变量的正确输出编码只会阻止一般情况下的XSS (旁注:静态和可信内容不必编码,但此级别为细节不适合这里的答案)。

话虽如此,根据您使用的环境,还有其他保护措施可能对某些特定情况有所帮助。但是,你不应该仅依赖于这些,但它们有助于增加防线。

一种这样的防御内置于浏览器中。如果浏览器在查询中检测到其中一个参数是Javascript,然后在结果页面中反映相同的Javascript,则某些浏览器实际上不会运行该操作,因为它是反射XSS的一种明显形式。此行为由X-XSS-Protection response header控制,在最近的浏览器中,您可以打开或关闭它。问题是到目前为止还不够。例如,它仅对反射的XSS有效,此时请求中的Javascript会反映在响应中。它可以在输入时存储在数据库中并写入不同的应用程序响应(存储的XSS),在这种情况下保护是无用的。浏览器保护也不会发现许多攻击向量(“利用XSS的方式”),尤其是当输入写入Javascript上下文时。请注意,由于此保护是浏览器功能,因此它是浏览器特定的,不同的浏览器可能表现不同。

另请注意,可能存在其他保护措施,例如.NET强制请求验证以尝试过滤恶意输入以及html上下文的自动输出编码,但即使这些与浏览器保护一起也足以防止XSS。如上所述,XSS是一个输出编码问题,没有其他任何东西可以阻止它(除非在某些特殊情况下)。然后我甚至没有提到DOM XSS,这是一类完全不同的类似问题,但在这个答案中我想集中讨论浏览器中内置的保护以及操作的上下文。