Spring Security 自带防火墙!你都不知道自己的系统有多安全!
使用 URL 地址编码之后,是 %2F%2F,其中 F 大小写无所谓,所以请求地址中也能不出现 “%2f%2f”, “%2f%2F”, “%2F%2f”, “%2F%2F”。@MatrixVariable 是 Spring3.2 中带来的功能,这种方式拓展了请求参数的传递格式,使得参数之间可以用。设置完成之后,再去访问相同的接口,可以看到,此时虽然还是报错,但是错误是 404 了,而不是一开始那个
先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。





既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
正文
DefaultHttpFirewall 的限制相对于 StrictHttpFirewall 要宽松一些,当然也意味着安全性不如 StrictHttpFirewall。
Spring Security 中默认使用的是 StrictHttpFirewall。
那么 StrictHttpFirewall 都是从哪些方面来保护我们的应用呢?我们来挨个看下。
2.1 只允许白名单中的方法
首先,对于请求的方法,只允许白名单中的方法,也就是说,不是所有的 HTTP 请求方法都可以执行。
这点我们可以从 StrictHttpFirewall 的源码中看出来:
public class StrictHttpFirewall implements HttpFirewall {
private Set allowedHttpMethods = createDefaultAllowedHttpMethods();
private static Set createDefaultAllowedHttpMethods() {
Set result = new HashSet<>();
result.add(HttpMethod.DELETE.name());
result.add(HttpMethod.GET.name());
result.add(HttpMethod.HEAD.name());
result.add(HttpMethod.OPTIONS.name());
result.add(HttpMethod.PATCH.name());
result.add(HttpMethod.POST.name());
result.add(HttpMethod.PUT.name());
return result;
}
private void rejectForbiddenHttpMethod(HttpServletRequest request) {
if (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
return;
}
if (!this.allowedHttpMethods.contains(request.getMethod())) {
throw new RequestRejectedException("The request was rejected because the HTTP method “” +
request.getMethod() +
“” was not included within the whitelist " +
this.allowedHttpMethods);
}
}
}
从这段代码中我们看出来,你的 HTTP 请求方法必须是 DELETE、GET、HEAD、OPTIONS、PATCH、POST 以及 PUT 中的一个,请求才能发送成功,否则的话,就会抛出 RequestRejectedException 异常。
那如果你想发送其他 HTTP 请求方法,例如 TRACE ,该怎么办呢?我们只需要自己重新提供一个 StrictHttpFirewall 实例即可,如下:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setUnsafeAllowAnyHttpMethod(true);
return firewall;
}
其中,setUnsafeAllowAnyHttpMethod 方法表示不做 HTTP 请求方法校验,也就是什么方法都可以过。或者也可以通过 setAllowedHttpMethods 方法来重新定义可以通过的方法。
2.2 请求地址不能有分号
不知掉大家有没有试过,如果你使用了 Spring Security,请求地址是不能有 ; 的,如果请求地址有 ; ,就会自动跳转到如下页面:

可以看到,页面的提示中已经说了,因为你的请求地址中包含 ;,所以请求失败。
什么时候请求地址中会包含 ; 呢?不知道小伙伴们在使用 Shiro 的时候,有没有注意到,如果你禁用了 Cookie,那么 jsessionid 就会出现在地址栏里,像下面这样:
http://localhost:8080/hello;jsessionid=xx
这种传递 jsessionid 的方式实际上是非常不安全的(松哥后面的文章会和大家细聊这个问题),所以在 Spring Security 中,这种传参方式默认就禁用了。
当然,如果你希望地址栏能够被允许出现 ; ,那么可以按照如下方式设置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
return firewall;
}
设置完成之后,再去访问相同的接口,可以看到,此时虽然还是报错,但是错误是 404 了,而不是一开始那个不允许 ; 的错了。

注意,在 URL 地址中,; 编码之后是 %3b 或者 %3B,所以地址中同样不能出现 %3b 或者 %3B
题外话
有的小伙伴可能不知道或者没用过,Spring3.2 开始,带来了一种全新的传参方式 @MatrixVariable。
@MatrixVariable 是 Spring3.2 中带来的功能,这种方式拓展了请求参数的传递格式,使得参数之间可以用 ; 隔开,这种传参方式真是哪壶不开提哪壶。因为 Spring Security 默认就是禁止这种传参方式,所以一般情况下,如果你需要使用 @MatrixVariable 来标记参数,就得在 Spring Security 中额外放行。
接下来我通过一个简单的例子来和大家演示一下 @MatrixVariable 的用法。
我们新建一个 /hello 方法:
@RequestMapping(value = “/hello/{id}”)
public void hello(@PathVariable Integer id,@MatrixVariable String name) {
System.out.println("id = " + id);
System.out.println("name = " + name);
}
另外我们还需要配置一下 SpringMVC,使 ; 不要被自动移除了:
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
然后启动项目(注意,Spring Security 中也已经配置了允许 URL 中存在 ;),浏览器发送如下请求:
http://localhost:8080/hello/123;name=javaboy
控制台打印信息如下:
id = 123
name = javaboy
可以看到,@MatrixVariable 注解已经生效了。
2.3 必须是标准化 URL
请求地址必须是标准化 URL。
什么是标准化 URL?标准化 URL 主要从四个方面来判断,我们来看下源码:
StrictHttpFirewall#isNormalized:
private static boolean isNormalized(HttpServletRequest request) {
if (!isNormalized(request.getRequestURI())) {
return false;
}
if (!isNormalized(request.getContextPath())) {
return false;
}
if (!isNormalized(request.getServletPath())) {
return false;
}
if (!isNormalized(request.getPathInfo())) {
return false;
}
return true;
}
getRequestURI 就是获取请求协议之外的字符;getContextPath 是获取上下文路径,相当于是 project 的名字;getServletPath 这个就是请求的 servlet 路径,getPathInfo 则是除过 contextPath 和 servletPath 之后剩余的部分。
这四种路径中,都不能包含如下字符串:
“./”, “/…/” or “/.”
2.4 必须是可打印的 ASCII 字符
如果请求地址中包含不可打印的 ASCII 字符,请求则会被拒绝,我们可以从源码中看出端倪:
StrictHttpFirewall#containsOnlyPrintableAsciiCharacters
private static boolean containsOnlyPrintableAsciiCharacters(String uri) {
int length = uri.length();
for (int i = 0; i < length; i++) {
char c = uri.charAt(i);
if (c < ‘\u0020’ || c > ‘\u007e’) {
return false;
}
}
return true;
}
2.5 双斜杠不被允许
如果请求地址中出现双斜杠,这个请求也将被拒绝。双斜杠 // 使用 URL 地址编码之后,是 %2F%2F,其中 F 大小写无所谓,所以请求地址中也能不出现 “%2f%2f”, “%2f%2F”, “%2F%2f”, “%2F%2F”。
如果你希望请求地址中可以出现 // ,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedDoubleSlash(true);
return firewall;
}
2.6 % 不被允许
如果请求地址中出现 %,这个请求也将被拒绝。URL 编码后的 % 是 %25,所以 %25 也不能出现在 URL 地址中。
如果希望请求地址中可以出现 %,可以按照如下方式修改:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
2.7 正反斜杠不被允许
学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
2.7 正反斜杠不被允许
学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-JnlQv7rB-1713174851426)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
更多推荐
所有评论(0)