§允许的主机过滤器
Play 提供了一个过滤器,允许您配置哪些主机可以访问您的应用程序。这对于防止缓存中毒攻击非常有用。有关此攻击工作原理的详细说明,请参阅 这篇博文。该过滤器引入了允许的主机白名单,并向所有主机不匹配白名单的请求发送 400(错误请求)响应。
即使在开发中,这也是一个重要的过滤器,因为 DNS 重绑定攻击可以针对 Play 的开发人员实例使用:请参阅 Rails Webconsole DNS 重绑定,了解短暂 DNS 重绑定如何攻击在 localhost 上运行的服务器的示例。
请注意,如果您针对具有 AllowedHostsFilter 的 Play 应用程序运行功能测试,那么 FakeRequest
和 Helpers.fakeRequest()
将创建一个请求,该请求已将 HOST
设置为 localhost
。
§启用允许的主机过滤器
注意:从 Play 2.6.x 开始,允许的主机过滤器包含在 Play 的默认过滤器列表中,这些过滤器会自动应用于项目。有关更多信息,请参阅 过滤器页面。
要手动启用过滤器,请在application.conf
中的过滤器中添加允许的主机过滤器。
play.filters.enabled += play.filters.hosts.AllowedHostsFilter
§配置允许的主机
您可以使用application.conf
配置过滤器允许哪些主机。请参阅 Play 过滤器reference.conf
以查看默认值。
play.filters.hosts.allowed
是一个字符串列表,格式为.example.com
或example.com
。使用前导点,模式将匹配 example.com 和所有子域(www.example.com
、foo.example.com
、foo.bar.example.com
等)。没有前导点,它只会匹配确切的域名。如果您的应用程序在特定端口上运行,您还可以包含端口号,例如.example.com:8080
。
您可以使用.
模式匹配所有主机(不建议在生产环境中使用)。请注意,过滤器还会从主机末尾删除点字符,因此example.com
模式将匹配example.com.
。
以下是一个示例配置。
play.filters.hosts {
# Allow requests to example.com, its subdomains, and localhost:9000.
allowed = [".example.com", "localhost:9000"]
}
§通过路由修饰符应用于路由
您可能会发现,某些路由无法与允许的主机过滤一起正常使用。这通常是负载均衡器健康检查的情况,这些检查通常使用服务器的 IP 地址作为主机名。与其完全禁用此重要的安全功能,您可以使用路由修饰符白名单将有问题的路由从过滤器中排除,同时默认情况下将其打开。
例如,默认配置定义了一个anyhost
路由标签,可用于将一个或多个路由从过滤器中排除。
play.filters.hosts.routeModifiers.whiteList = [anyhost]
使用此配置,标记为anyhost
的路由将免受允许的主机过滤器的影响,例如,您的路由文件可能如下所示
+anyhost
GET /healthcheck controllers.HealthController.healthcheck
如果白名单为空并且黑名单已定义,则允许的主机过滤器将仅应用于标记为黑名单配置中存在的标签的路由。例如,以下配置将仅将允许的主机过滤器应用于标记为external
的路由。
play.filters.hosts.routeModifiers.whiteList = []
play.filters.hosts.routeModifiers.blackList = [external]
使用此配置,您的路由文件可能如下所示
+external
GET / controllers.HomeController.index
GET /healthcheck controllers.HealthController.healthcheck
§测试
由于 AllowedHostsFilter 过滤器是自动添加的,因此功能测试需要添加 Host HTTP 头。
如果您使用的是 FakeRequest
或 Helpers.fakeRequest
,则会自动为您添加 Host
HTTP 头。如果您使用的是 play.mvc.Http.RequestBuilder
,则可能需要手动添加一行代码来添加该头。
Http.RequestBuilder request =
new Http.RequestBuilder()
.method(GET)
.header(Http.HeaderNames.HOST, "localhost")
.uri("/xx/Kiwi");
下一步:配置 HTTPS 重定向
发现此文档中的错误?此页面源代码可在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区开始对话。