3

我希望这个问题是不言自明的。我正在使用 CAS 服务器设置 Spring Security 环境。因为完全相同的应用程序部署在同一台服务器上,但是可以通过不同的主机名(.de 域、.com 域,可能不止这些)访问服务器,我们希望在测试系统和本地系统上部署相同的应用程序同样,我构建了一个动态服务,其中服务 URL 是从请求 URL 派生的。

public static String makeDynamicUrlFromRequest(ServiceProperties serviceProperties, HttpServletRequest request) {
        String serviceUrl = "https://backup-url.de/login";
        URI uri = null;
        try {
            uri = new URI(request.getRequestURL().toString());
        } catch (URISyntaxException e) {
            logger.error("Someone tried accessing a disallowed service!", e);
        }

        if(uri != null){
            serviceUrl = uri.getScheme() + "://" + uri.getHost() + "/login";
        }

        return serviceUrl;
    }

有可能欺骗这个吗?如果是,额外的正则表达式检查是否为我提供了必要的安全性?

4

1 回答 1

1

@developerwjk
“如果他们修改了请求 URL,您将如何获得请求?”
HTTP 服务器只是一个侦听 TCP 端口、等待一些传入文本并写出一些文本作为响应的程序。(一个普通的 Web 服务器可以用 20 行代码编写。)它只能看到连接到它的任何东西的 IP 地址和端口。这甚至可以是一个代理,或者某种其他类型的中间件。如果你不告诉程序“顺便说一句,我是通过 URL 联系到你的http://my.com/myapp/servlet”,那么它只是不知道例如浏览器将如何访问它。

@Schaka我不知道您的特定设置,但是对于jetty9,结果getRequestURL由请求标头中的请求URL确定,并且-如果缺少前者-Host参数中的URL。也就是说,如果您连接my.com并发送以下请求:

POST http://spoofed1.tld/myapp/servlet HTTP/1.1
Host: spoofed2.tld

(记住该Host参数是强制性的。)
然后getRequestURL将返回http://spoofed1.tld/myapp/servlet

如果你发送这个:

POST /myapp/servlet HTTP/1.1
Host: spoofed2.tld

然后码头本身会回应

HTTP/1.1 302 Found
Location: http://spoofed2.tld/myapp/servlet
Content-Length: 0
Server: Jetty(<some version number>)

所以答案是肯定的,HttpServletRequest.getRequestURL() 是可欺骗的!通过修改请求 URL 和/或Host请求标头。

于 2021-10-19T09:47:26.820 回答