未执行的内容是否仍被视为 XSS?

信息安全 xss owasp 扎普 反射-xss
2021-09-12 13:44:29

我正在处理一份 OWASP Zap 报告,该报告已将域上的多个 URL 标记为易受 XSS 攻击,但该漏洞永远不会在浏览器可执行的上下文中输出。例如,报告显示

path/contacts.php?search=John%3Balert%281%29

解码:path/contacts.php?search=John;alert(1)

作为易受攻击的 URL。

应用程序在对用户的响应中确实反映了这个特定的内容:

var search = "John;alert(1)";

我认为这是在应用程序中触发警报作为 XSS 攻击的原因。

这里的 XSS 是攻击者可以在此上下文中引入他们想要的任何任意代码并将其反映到用户的浏览器,但此代码永远不会执行。

手动测试漏洞,应用程序在输出响应之前转换尝试攻击中的字符(使用 PHP 的 htmlentities 函数),所以像

?search=John";alert(1);

返回为:

var search = "John";alert(1);";

所以问题是,这是否仍然是一个活跃的 XSS 漏洞?

注意:我注意到仍然有机会正确验证输入参数,但我担心的是这里的安全隐患。

3个回答

这对于自动扫描工具来说非常常见。他们只能如此聪明,因此总是会发生误报(就像漏报一样)。因此,任何标记的漏洞都应手动验证。这就是为什么,例如,漏洞赏金计划总是有“不考虑自动扫描程序的结果”之类的通知——运行扫描程序并报告漏洞很容易,但安全团队可能已经这样做了,所以 99% 的时间这是浪费时间。然而,这导致了下一个问题:

这个特定的脚本是否正确处理了这个输入?

这是一个很难回答的问题。您已经检查了最明显的解决方法(注入双引号),但还有更多选择。我想到的两个是字符编码的修改和反斜杠的测试。前者有点远,所以我只关注后者:

  1. 尝试在输入末尾注入反斜杠 ?search=whatever\
  2. 如果应用程序没有转义您的反斜杠,则 javascript 将是: var search = "whatever\";
  3. 这将破坏javascript。如果幸运的话,它还可以让您通过第二个参数注入 XSS。

最后一步可以举个例子。想象一下完整的 javascript 是这样的:

var a="[search input]";var b="[name input]";

需要明确的是,代码已被最小化以节省带宽。这将很重要。此外,两者都没有逃脱反斜杠。因此,您可以将这样的有效负载放在一起:

?search=\&name=;alert(1)//

你最终会得到这个 javascript:

var a="\";var b=";alert(1)//";

这是一个有效的 XSS 有效负载。您的反斜杠转义了var a = "语句的结束双引号,因此第二个变量的起始双引号最终成为结束双引号。结果,您对第二个输入的输入最终以纯 javascript 的形式执行 - 您只需要以分号结尾,然后是注释字符即可摆脱最后的结束双引号。

现在你可能不会有任何运气让它工作。如果他们也正确处理反斜杠,那么您将不会有任何运气。如果这些行被分成单独的行,那么你也不会有任何运气(在大多数版本的 javascript 中,需要一个续行字符,但有时这里有一些非标准的浏览器行为)。但是,如果他们忘记转义反斜杠并且您可以在同一行上找到两个输入,那么您就有一个简单的 XSS 漏洞。

概括

确实,尽管这突出了主要内容,这就是为什么这些事情如此棘手:所需的利用类型在数据注入的上下文中差异很大,并且自动扫描仪实际上不可能测试所有内容。因此,作为渗透测试人员,您必须熟悉所有选项,这非常棘手!幸运的是,这也是 XSS 如此普遍的原因——程序员同样不善于理解他们必须小心防范 XSS 漏洞的所有方法。

是的,这看起来确实是一个误报。显然,您应该像您所做的那样仔细检查手动测试。你能确认这是页面上唯一反映有效负载的地方吗?我提出了这个 ZAP 错误:https ://github.com/zaproxy/zaproxy/issues/5958

你 test withJohn";alert(1);语法不正确的这就是为什么即使有漏洞,也不会发生任何事情。浏览器只会在 JavaScript 中报告错误。即,该符号"使您的 JavaScript 无效。

要测试您的客户端代码的行为方式,您应该使用有效的JavaScript。

alert(1);在您的请求中使用以下 JavaScript 代码

path/contacts.php?search=alert%281%29

如果此代码在您的浏览器中执行,则意味着存在漏洞。如果不执行,这将没有任何意义(它不会证明没有漏洞),需要对您的代码进行进一步分析。