CodeQL 文档

来自远程源的 URL 重定向

ID: cs/web/unvalidated-url-redirection
Kind: path-problem
Security severity: 6.1
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-601
Query suites:
   - csharp-code-scanning.qls
   - csharp-security-extended.qls
   - csharp-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

直接将用户输入合并到 URL 重定向请求中而不验证输入会导致网络钓鱼攻击。在这些攻击中,毫无戒心的用户可能会被重定向到一个与他们打算访问的真实网站非常相似的恶意网站,但该网站由攻击者控制。

建议

为了防止不受信任的 URL 重定向,建议避免将用户输入直接放入重定向 URL 中。相反,在服务器上维护一个授权重定向列表;然后根据提供的用户输入从该列表中进行选择。

如果无法做到这一点,则应以其他方式验证用户输入,例如,通过验证目标 URL 是否与当前页面位于同一主机上。

示例

以下示例显示了在没有验证输入的情况下直接在 URL 重定向中使用 HTTP 请求参数,这会导致网络钓鱼攻击

using System;
using System.Web;

public class UnvalidatedUrlHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext ctx)
    {
        // BAD: a request parameter is incorporated without validation into a URL redirect
        ctx.Response.Redirect(ctx.Request.QueryString["page"]);
    }
}

解决此问题的一种方法是在执行重定向之前根据已知的固定字符串验证用户输入

using System;
using System.Web;
using System.Collections.Generic;

public class UnvalidatedUrlHandler : IHttpHandler
{
    private List<string> VALID_REDIRECTS = new List<string>{ "http://cwe.mitre.org/data/definitions/601.html", "http://cwe.mitre.org/data/definitions/79.html" };

    public void ProcessRequest(HttpContext ctx)
    {
        if (VALID_REDIRECTS.Contains(ctx.Request.QueryString["page"]))
        {
            // GOOD: the request parameter is validated against a known list of strings
            ctx.Response.Redirect(ctx.Request.QueryString["page"]);
        }
    }
}

或者,我们可以通过检查 URL 是相对的还是位于已知的良好主机上来检查目标 URL 是否未重定向到其他主机

using System;
using System.Web;

public class UnvalidatedUrlHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext ctx)
    {
        var urlString = ctx.Request.QueryString["page"];
        var url = new Uri(urlString, UriKind.RelativeOrAbsolute);

        var url = new Uri(redirectUrl, UriKind.RelativeOrAbsolute);
        if (!url.IsAbsoluteUri) {
            // GOOD: The redirect is to a relative URL
            ctx.Response.Redirect(url.ToString());
        }

        if (url.Host == "example.org") {
            // GOOD: The redirect is to a known host
            ctx.Response.Redirect(url.ToString());
        }
    }
}

请注意,按照编写,上面的代码将允许重定向到 example.com 上的 URL,这是无害的,但可能不是故意的。您可以将自己的域(如果已知)替换为 example.com 以防止这种情况发生。

参考

  • ©GitHub 公司
  • 条款
  • 隐私