易受攻击的 JavaScript 函数调用

Vulnerable JavaScript function call

我的应用程序中有以下 JavaScipt 函数,它会在一分钟后将用户重定向到登录页面:

(function redirect_expired() {
    $j.get('/app/ExpiredSession', function (resp) {
        if (resp && resp.redirectTo) {
            window.location.href = resp.redirectTo;
        }
    });
    setInterval(redirect_expired, 60 * 1000);
})();

和一个相关的 Java servlet 函数:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    PrintWriter pw = resp.getWriter();
    resp.setContentType("application/json");
    if (req.getSession != null && req.getSession().getAttribute("authorizationBean") == null) {
        pw.print("{\"redirectTo\": \"" + req.getContentPath() + "\"}");
    } else {
        pw.print("{\"redirectTo\": \"\"}");
    }
    pw.close();
}

当我使用 Fortify 扫描我的应用程序时,我在 Java 脚本函数中发现了以下漏洞:

谁能解释一下这个重定向调用到底出了什么问题 window.location.href = resp.redirectTo; 以及我该如何解决它?

也许我可以在 Java 端添加一些额外的输入检查?

好吧,在 Java 端执行此操作在这种情况下可能行不通。考虑警告的这一部分:"can aid phishing attacks" - 如果攻击者能够提供恶意的 link,您可以将用户重定向到钓鱼网站(看起来像您的网站,但实际上不是),这让用户输入他们的凭据,然后将请求发送到您的服务器(甚至可能再次重定向)。即使您的服务器会识别出钓鱼站点已经可以访问用户的凭据。

警告的另一部分是 "can result in the browser executing malicious code"(我强调)- 已经暗示正在执行的代码它被发送到您的服务器之前,因此您可以连这种攻击都认出来了

你如何解决这个问题?好吧,我不是 Java 脚本专家,但请考虑 "JS function passes unvalidated data to an HTTP redirect function" - 这表明您应该验证输入或仅使用 "pre-validated" url。

有关更多信息,请查看此处:https://owasp.org/www-project-cheat-sheets/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html

JS function passes unvalidated data to an HTTP redirect function on line window.location.href = resp.redirectTo;Allowing unvalidated input to control the URL used in redirect can aid phishing attacks.

您的重定向正在使用从您的 get 返回的值。您无法确定收到的 url 是否就是您期望的 url。如果您的 /app/ExpiredSession 页面遭到破坏,您可能会收到恶意 url.

在警告的情况下,他们建议 phishing attacks which could pose as another site, in the attempt to get a users credentials (for example). In your case, as you are redirecting to a different page, you could be subject to "Reverse Tabnabbing" 恶意页面可能冒充您的网站并欺骗用户,让他们相信他们从未离开过您的页面。

您可能希望通过不同的方式验证 url 是否可信。一个简单的方法是存储受信任的 url 或域的列表,并在重定向到它之前检查您是否识别 url。

更具体的方法是使用SSL pinning。这将确保您只与您信任的服务器通信并通过 SSL(使用 https)。这通过保存 SSL 证书的指纹并将其与请求的目标进行比较来实现。如果它们不同,则我们认为该站点已受到威胁,不应继续请求。

两者的结合意味着您在发出请求时仅与受信任的站点通信,并且您仅重定向到您 "know" 所在的站点。


JS function passes unvalidated data to an HTTP redirect function on line window.location.href = resp.redirectTo;. Allowing unvalidated input to control the URL used in redirect can aid phishing attacks.

可能会向url中注入恶意代码,您可以通过运行

进行测试
window.location.href = "javascript:alert(1)"

有一些不错OWASP suggestions on how to validate urls

  • 重定向到本地页面的以 / 开头的输入不安全。 //example.org 是有效的 URL.
  • 以所需域名开头的输入不安全。 https://example.org.attacker.com 有效。
  • 只允许 HTTP(S) 协议。应阻止所有其他协议,包括 JavaScript URI,例如 javascript:alert(1)
  • 应阻止 data:text/html,<script>alert(document.domain)</script> 等数据 URI
  • 包含 CRLF 字符的 URI 可能导致 header 注入或响应分裂攻击,应予以阻止

这里是 OWASP

建议的 Javascript 使用正则表达式的示例
var validateUrl = new RegExp(/^((((https?|ftps?|gopher|telnet|nntp):\/\/)|(mailto:|news:))(%[0-9A-Fa-f]{2}|[-()_.!~*';/?:@&=+$,A-Za-z0-9])+)([).!';/?:,][[:blank:|:blank:]])?$/)
var url = 'http://google.com' 
if (url.match(validateUrl)) {
    console.log('Redirecting to', url)
} else {
     // Do not do anything with the url variable here, executing it could be dangerous
    console.log('Not a valid url')
}

此正则表达式将防止上述情况,但 https://example.org.attacker.com 除外。但是,这种情况通过使用上述具有受信任域列表的建议得到解决。 You can see for yourself here