Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of SpringSecurity Series request with Firewall enabled by default

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the example analysis that the firewall is enabled by default for the request of SpringSecurity series. The content is very detailed. Interested friends can use it for reference. I hope it will be helpful to you.

Of course, you can write it yourself, but in most cases, we are not professional Web security engineers, so the only thing to consider is authentication and authorization. Once these two problems are dealt with, it seems that the system is very secure.

That's not true!

All kinds of Web attacks occur every day, such as fixed session attacks, csrf attacks, and so on. If you do not understand these attacks, then the system will certainly not be able to defend against these attacks.

The advantage of using Spring Security is that even if you don't know about these attacks, you don't have to worry about them, because Spring Security has already defended you.

We often say that compared to Shiro,Spring Security, heavyweight has heavyweight benefits, such as full functionality and more complete security management. With Spring Security, you have no idea how secure your system is!

Today I'm going to talk to you about the firewall mechanism that comes with Spring Security.

All right, cut the crap. Let's take a look at the article.

1.HttpFirewall

A HttpFirewall is provided in Spring Security. If you look at the name, you can see that this is a request firewall that can automatically handle some illegal requests.

HttpFirewall currently has two implementation classes:

One is the strict mode firewall setting, and there is a default firewall setting.

The restrictions of DefaultHttpFirewall are looser than those of StrictHttpFirewall, which of course means that security is not as secure as StrictHttpFirewall.

StrictHttpFirewall is used by default in Spring Security.

two。 Protective measures

So in what ways does StrictHttpFirewall protect our applications? Let's take a look at one by one.

2.1 only methods in the whitelist are allowed

First of all, for the requested methods, only the methods in the whitelist are allowed, that is, not all HTTP request methods can be executed.

We can see this from the source code of 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);}}

We can see from this code that your HTTP request method must be one of DELETE, GET, HEAD, OPTIONS, PATCH, POST, and PUT for the request to be sent successfully, otherwise, a RequestRejectedException exception will be thrown.

What if you want to send other HTTP request methods, such as TRACE? We only need to provide a new StrictHttpFirewall instance ourselves, as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setUnsafeAllowAnyHttpMethod (true); return firewall;}

Where the setUnsafeAllowAnyHttpMethod method means that no HTTP request method verification is done, that is, any method can be passed. Alternatively, you can redefine the methods that can be passed through the setAllowedHttpMethods method.

2.2 the request address cannot have a semicolon

I wonder if you have ever tried that if you use Spring Security, you cannot have a request address; yes, if you have a request address, you will automatically jump to the following page:

As you can see, it's already said in the prompt on the page that the request failed because your request address contains;.

When will the request address include;? I wonder if my buddies have noticed that when using Shiro, if you disable Cookie, jsessionid will appear in the address bar, like this:

Http://localhost:8080/hello;jsessionid=xx

This way of passing jsessionid is actually very unsafe (Brother Song will talk about this in more detail later), so in Spring Security, this way of passing parameters is disabled by default.

Of course, if you want the address bar to be allowed to appear, you can set it as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setAllowSemicolon (true); return firewall;}

After the setup is completed, you can visit the same interface. You can see that although the error is still reported at this time, the error is 404, not the one that is not allowed at the beginning.

Note that in the URL address,% 3b or% 3B is encoded after;, so% 3b or% 3B cannot appear in the address either.

Extraneous remarks

Some friends may not know or have not used it, Spring3.2 began to bring a new way to pass parameters @ MatrixVariable.

@ MatrixVariable is a function brought by Spring3.2. This method expands the format of passing request parameters so that they can be used between parameters. Apart, this method of passing parameters is really different from each other. Because Spring Security forbids this method of passing parameters by default, in general, if you need to use @ MatrixVariable to mark parameters, you have to release extra in Spring Security.

Next, I'll show you the use of @ MatrixVariable with a simple example.

Let's create a new / hello method:

@ RequestMapping (value = "/ hello/ {id}") public void hello (@ PathVariable Integer id,@MatrixVariable String name) {System.out.println ("id =" + id); System.out.println ("name =" + name);}

In addition, we also need to configure SpringMVC so that; do not be automatically removed:

@ Configuration public class WebMvcConfig extends WebMvcConfigurationSupport {@ Override protected void configurePathMatch (PathMatchConfigurer configurer) {UrlPathHelper urlPathHelper = new UrlPathHelper (); urlPathHelper.setRemoveSemicolonContent (false); configurer.setUrlPathHelper (urlPathHelper);}}

Then start the project (note that Spring Security has also been configured to allow URL to exist;), and the browser sends the following request:

Http://localhost:8080/hello/123;name=javaboy

The console prints the following information:

Id = 123name = javaboy

As you can see, the @ MatrixVariable annotation is already in effect.

2.3 must be standardized URL

The request address must be a standardized URL.

What is standardized URL? Standardized URL is mainly judged from four aspects. Let's take a look at the source code:

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 is to get characters outside the request protocol; getContextPath is to get the context path, which is equivalent to the name of project; getServletPath is the servlet path of the request, and getPathInfo is the rest after contextPath and servletPath.

None of these four paths can contain the following strings:

". /", "/.. /" or "/." 2.4 must be printable ASCII characters

If the request address contains non-printable ASCII characters, the request will be rejected, as we can see in the source code:

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 double slashes are not allowed

If a double slash appears in the request address, the request will also be rejected. After the double slash / / is encoded with the URL address, it is% 2F%2F, where F case does not matter, so "% 2f%2f", "% 2f%2F", "% 2F%2f", "% 2F%2F" can not appear in the request address.

If you want / / to appear in the request address, you can configure it as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setAllowUrlEncodedDoubleSlash (true); return firewall;} 2.6% is not allowed

If% appears in the request address, the request will also be rejected. The URL encoded% is 25, so 25 cannot appear in the URL address either.

If you want% to appear in the request address, you can modify it as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setAllowUrlEncodedPercent (true); return firewall;} 2.7 forward and backward slashes are not allowed

If the request address contains the slash-encoded character% 2F or% 2f, the request will be rejected.

If the request address contains a backslash\ or the backslash encoded character% 5C or% 5c, the request will be rejected.

If you want to remove the above two restrictions, you can configure them as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setAllowBackSlash (true); firewall.setAllowUrlEncodedSlash (true); return firewall;} 2.8. Not allowed

If it exists in the request address. If the encoded characters% 2e,% 2e, the request will be denied.

If you need support, configure it as follows:

@ Bean HttpFirewall httpFirewall () {StrictHttpFirewall firewall = new StrictHttpFirewall (); firewall.setAllowUrlEncodedPeriod (true); return firewall;}

It is important to emphasize that the restrictions mentioned above are for the requestURI of the request, not for the request parameters. For example, the format of your request is:

Http://localhost:8080/hello?param=aa%2ebb

So the restrictions in section 2.7 have nothing to do with you.

This is easy to see from the StrictHttpFirewall source code:

Public class StrictHttpFirewall implements HttpFirewall {@ Override public FirewalledRequest getFirewalledRequest (HttpServletRequest request) throws RequestRejectedException {rejectForbiddenHttpMethod (request); rejectedBlacklistedUrls (request); rejectedUntrustedHosts (request); if (! isNormalized (request)) {throw new RequestRejectedException ("The request was rejected because the URL was not normalized.");} String requestUri = request.getRequestURI (); if (! containsOnlyPrintableAsciiCharacters (requestUri)) {throw new RequestRejectedException ("The requestURI was rejected because it can only contain printable ASCII characters.") } return new FirewalledRequest (request) {@ Override public void reset () {}};} private void rejectedBlacklistedUrls (HttpServletRequest request) {for (String forbidden: this.encodedUrlBlacklist) {if (encodedUrlContains (request, forbidden)) {throw new RequestRejectedException ("The request was rejected because the URL contained a potentially malicious String\"+ forbidden +"\ ") }} for (String forbidden: this.decodedUrlBlacklist) {if (decodedUrlContains (request, forbidden)) {throw new RequestRejectedException ("The request was rejected because the URL contained a potentially malicious String\"+ forbidden +"\ ");} private static boolean encodedUrlContains (HttpServletRequest request, String value) {if (valueContains (request.getContextPath (), value)) {return true;} return valueContains (request.getRequestURI (), value) Private static boolean decodedUrlContains (HttpServletRequest request, String value) {if (valueContains (request.getServletPath (), value)) {return true;} if (valueContains (request.getPathInfo (), value)) {return true;} return false;} private static boolean valueContains (String value, String contains) {return value! = null & & value.contains (contains);}}

The rejectedBlacklistedUrls method is used to verify URL, and the logic of this method is very simple, so I won't repeat it.

This is the example analysis of the firewall enabled by default for the request of SpringSecurity series. I hope the above content can be of some help and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report