赞
踩
Spring Boot 开箱即用地配置了许多安全方面。其中之一是 HTTP 防火墙,它被实现为接口类型 HttpFirewall。在讨论 Spring Security 时,通常会非常关注 Spring 的安全过滤器(这是理所当然的),但不明显的是 HttpFirewall 是我们的第一道防线。
这篇文章涵盖了 Spring Boot 2 和 Spring Security 5。以下 Spring Boot 启动器依赖项是启动和运行以及自动配置 HttpFirewall 所需的全部内容。
1
2
3
4
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
|
如果您有兴趣阅读有关 Spring Boot 的默认安全配置的信息,请在此处查看我的帖子。
Spring 通过将 HttpFirewall 包含到其 FilterChainProxy中来实现这一点 ,然后 在任何 HTTP 请求通过过滤器链发送之前执行。默认情况下,StrictHttpFirewall 实现由 FilterChainProxy 实例化,它将拒绝和可疑请求(稍后会详细介绍)并带有 RequestRejectedException。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class FilterChainProxy extends GenericFilterBean {
// ~ Static fields/initializers
// =====================================================================================
private static final Log logger = LogFactory.getLog(FilterChainProxy.class);
// ~ Instance fields
// ================================================================================================
.... omitted for brevity
private HttpFirewall firewall = new StrictHttpFirewall();
.... omitted for brevity
|
还有另一种实现称为 DefaultHttpFirewall 具有讽刺意味的是,它不是默认的,并且比其更严格的对应物更宽容。它试图通过尝试清理 URL 而不是直接拒绝它来纠正问题,但是 Spring 建议使用 StrictHttpFirewall 代替 - 更安全。
在任何 HttpFirewall 实现中都没有记录器,也没有记录消息。这可能是为什么这个 Spring Security 特性被忽视的原因,因为我们从未在日志中看到任何提及它,尤其是在启动时。
基本上,Http 防火墙实施的规则会强制增加安全性,以净化和保护我们免受可能有害的精心制作的 URL 的侵害,甚至在它们到达安全过滤器链之前。
一些,但不是所有的这些保护可以通过 setter 方法定制/覆盖。我将在这里专门介绍 StrictHttpFirewall 实现,因为这样做更安全。
拒绝不属于允许的安全列表的 HTTP 方法。这被指定用于阻止 HTTP 动词篡改和 XST 攻击。默认列表允许 HTTP 方法DELETE、GET、HEAD、OPTIONS、PATCH、POST、PUT。
如果您尝试发送 TRACE 或 CONNECT,那么这将被视为禁止的 HTTP 方法,因此会 抛出RequestRejectedException 消息“请求被拒绝,因为 HTTP 方法 <HTTP Method> 未包含在安全列表中”。
您可以通过setAllowedHttpMethods方法指定您自己的安全列表来覆盖此行为。 也可以通过调用setUnsafeAllowAnyHttpMethod(boolean)将其关闭并允许任何 HTTP 方法,但这将使您面临 HTTP 动词篡改和 XST 攻击。
URL/URI 规范化是用于确定语法上不同的 URI 是否相同的过程。例如 ..
1
2
3
4
|
http://example.com/foo → http://example.com/foo/
http://example.com/default.asp → http://example.com/
http://example.com:80/ → http://example.com/
http://example.com/foo//bar.html → http://example.com/foo/bar.html
|
现在,如果我们从安全的角度来看,这意味着一些黑客可以以绕过安全约束的方式制作某些 URL。
您不能禁用此功能,因为它被认为具有极高的风险。如果你想放松安全性,你总是可以回退到 DefaultHttpFirewall 或者实现你自己的 HttpFirewall,结合严格和稍微宽松的安全约束。
如果无法规范化 http 请求, 则会 抛出RequestRejectedException 消息“请求被拒绝,因为 URL 未规范化”。
这很棘手,因为表面上看起来一切正常,但实际上您的网站www.yourbank.com实际上可能是另一个www.yourb a nk.com,因为 URL 中的“ a ”实际上是一个 Unicode 字符,如 http://www。你的а ; nk ,com/ 看起来像英文 ASCII 字符“a”,但不是!
HttpFirewall 将确保 URL 包含 0x20 到 0x7e 范围内的可打印 ASCII 字符,如果不是,它将抛出 RequestRejectedException 消息“请求URI 被拒绝,因为它只能包含可打印的 ASCII 字符”。
也没有办法禁用它,因为禁用这个约束被认为是非常危险的。
我们以拒绝包含以下内容的 http 请求的 URL 阻止列表结束...
它们都有其独特的安全漏洞(我不会深入探讨),但是如果遇到它们,您将收到 RequestRejectedException 消息“请求被拒绝,因为 URL 包含潜在的恶意字符串 <forbidden_string>”。
1
2
3
4
5
6
7
8
9
10
11
|
@Bean
public HttpFirewall looseHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowedHttpMethods(Arrays.asList("GET", "POST"));
firewall.setAllowSemicolon(true);
firewall.setAllowUrlEncodedSlash(true);
firewall.setAllowBackSlash(true);
firewall.setAllowUrlEncodedPercent(true);
firewall.setAllowUrlEncodedPeriod(true);
return firewall;
}
|
希望您现在对 Spring Security 开箱即用的功能有了更好的了解。HttpFirewall 可能不会引起很多媒体关注,但了解它如何保护我们可以大大帮助我们理解和定制我们的应用程序安全性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。