eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

Course – LSS – NPI (cat=Spring Security)
announcement - icon

If you're working on a Spring Security (and especially an OAuth) implementation, definitely have a look at the Learn Spring Security course:

>> LEARN SPRING SECURITY

1. Introduction

Spring Framework versions 5.0 to 5.0.4, 4.3 to 4.3.14, and other older versions had a directory or path traversal security vulnerability on Windows systems.

Misconfiguring the static resources allows malicious users to access the server’s file system. For instance, serving static resources using file: protocol provides illegal access to the file system on Windows.

The Spring Framework acknowledged the vulnerability and fixed it in the later releases.

Consequently, this fix guards the applications against path traversal attacks. However, with this fix, a few of the earlier URLs now throw an org.springframework.security.web.firewall.RequestRejectedException exception.

Finally, in this tutorial, let’s learn about org.springframework.security.web.firewall.RequestRejectedException and StrictHttpFirewall in the context of path traversal attacks.

2. Path Traversal Vulnerabilities

A path traversal or directory traversal vulnerability enables illegal access outside the web document root directory. For instance, manipulating the URL can provide unauthorized access to the files outside the document root.

Though most latest and popular webservers offset most of these attacks, the attackers can still use URL-encoding of special characters like “./”, “../” to circumvent the webserver security and gain illegal access.

Also, OWASP discusses the Path Traversal vulnerabilities and the ways to address them.

3. Spring Framework Vulnerability

Now, Let’s try to replicate this vulnerability before we learn how to fix it.

First, let’s clone the Spring Framework MVC examples. Later, let’s modify the pom.xml and replace the existing Spring Framework version with a vulnerable version. 

Clone the repository:

git clone [email protected]:spring-projects/spring-mvc-showcase.git

Inside the cloned directory, edit the pom.xml to include 5.0.0.RELEASE as the Spring Framework version:

<org.springframework-version>5.0.0.RELEASE</org.springframework-version>

Next, edit the web configuration class WebMvcConfig and modify the addResourceHandlers method to map resources to a local file directory using  file:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/resources/**")
      .addResourceLocations("file:./src/", "/resources/");
}

Later, build the artifact and run our web app:

mvn jetty:run

Now, when the server starts up, invoke the URL:

curl 'http://localhost:8080/spring-mvc-showcase/resources/%255c%255c%252e%252e%255c/%252e%252e%255c/%252e%252e%255c/%252e%252e%255c/%252e%252e%255c/windows/system.ini'

%252e%252e%255c is a double-encoded form of  ..\ and %255c%255c is a double-encoded form of \\.

Precariously, the response will be the contents of the Windows system file system.ini.

4. Spring Security HttpFirewall Interface

The Servlet specification does not precisely define the distinction between servletPath and pathInfo. Hence, there is an inconsistency among the Servlet containers in the translation of these values.

For instance, on Tomcat 9, for the URL http://localhost:8080/api/v1/users/1, the URI /1 is intended to be a path variable.

On the other hand, the following returns /api/v1/users/1:

request.getServletPath()

However, the command below returns a null:

request.getPathInfo()

Unable to distinguish the path variables from the URI can lead to potential attacks like Path Traversal / Directory Traversal attacks. For instance, a user can exploit system files on the server by including a \\,  /../, ..\ in the URL. Unfortunately, only some Servlet containers normalize these URLs.

Spring Security to the rescue. Spring Security consistently behaves across the containers and normalizes these kinds of malicious URLs utilizing a HttpFirewall interface. This interface has two implementations:

4.1. DefaultHttpFirewall

In the first place, let’s not get confused with the name of the implementation class. In other words, this is not the default HttpFirewall implementation.

The firewall tries to sanitize or normalize the URLs and standardizes the servletPath and pathInfo across the containers. Also, we can override the default HttpFirewall behavior by explicitly declaring a @Bean:

@Bean
public HttpFirewall getHttpFirewall() {
    return new DefaultHttpFirewall();
}

However, StrictHttpFirewall provides a robust and secured implementation and is the recommended implementation.

4.2. StrictHttpFirewall

StrictHttpFirewall is the default and stricter implementation of HttpFirewall. In contrast, unlike DefaultHttpFirewall, StrictHttpFirewall rejects any un-normalized URLs providing more stringent protection. In addition, this implementation protects the application from several other attacks like Cross-Site Tracing (XST) and HTTP Verb Tampering.

Moreover, this implementation is customizable and has sensible defaults. In other words, we can disable (not recommended) a few of the features like allowing semicolons as part of the URI:

@Bean
public HttpFirewall getHttpFirewall() {
    StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
    strictHttpFirewall.setAllowSemicolon(true);
    return strictHttpFirewall;
}

In short, StrictHttpFirewall rejects suspicious requests with a org.springframework.security.web.firewall.RequestRejectedException.

Finally, let’s develop a User Management application with CRUD operations on Users using Spring REST and Spring Security, and see StrictHttpFirewall in action.

5. Dependencies

Let’s declare Spring Security and Spring Web dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>3.1.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.1.5</version>
</dependency>

6. Spring Security Configuration

Next, let’s secure our application with Basic Authentication by creating a configuration class that creates a SecurityFilterChain bean:

@Configuration
public class HttpFirewallConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry ->
                    authorizationManagerRequestMatcherRegistry.requestMatchers("/error").permitAll().anyRequest().authenticated())
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}

By default, Spring Security provides a default password that changes for every restart. Hence, let’s create a default username and password in the application.properties:

spring.security.user.name=user
spring.security.user.password=password

Henceforth, we’ll access our secured REST APIs using these credentials.

7. Building a Secured REST API

Now, let’s build our User Management REST API:

@PostMapping
public ResponseEntity<Response> createUser(@RequestBody User user) {
    userService.saveUser(user);
    Response response = new Response()
      .withTimestamp(System.currentTimeMillis())
      .withCode(HttpStatus.CREATED.value())
      .withMessage("User created successfully");
    URI location = URI.create("/users/" + user.getId());
    return ResponseEntity.created(location).body(response);
}
 
@DeleteMapping("/{userId}")
public ResponseEntity<Response> deleteUser(@PathVariable("userId") String userId) {
    userService.deleteUser(userId);
    return ResponseEntity.ok(new Response(200,
      "The user has been deleted successfully", System.currentTimeMillis()));
}

Now, let’s build and run the application:

mvn spring-boot:run

8. Testing the APIs

Now, let’s start by creating a User using cURL:

curl -i --user user:password -d @request.json -H "Content-Type: application/json" 
     -H "Accept: application/json" http://localhost:8080/api/v1/users

Here is a request.json:

{
    "id":"1",
    "username":"navuluri",
    "email":"[email protected]"
}

Consequently, the response is:

HTTP/1.1 201
Location: /users/1
Content-Type: application/json
{
  "code":201,
  "message":"User created successfully",
  "timestamp":1632808055618
}

Now, let’s configure our StrictHttpFirewall to deny requests from all the HTTP methods:

@Bean
public HttpFirewall configureFirewall() {
    StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
    strictHttpFirewall
      .setAllowedHttpMethods(Collections.emptyList());
    return strictHttpFirewall;
}

Next, let’s invoke the API again. Since we configured StrictHttpFirewall to restrict all the HTTP methods, this time, we get an error.

In the logs, we have this exception:

org.springframework.security.web.firewall.RequestRejectedException: 
The request was rejected because the HTTP method "POST" was not included
  within the list of allowed HTTP methods []

Since Spring Security v6.1.5, we can use RequestRejectedHandler to customize the HTTP Status when there is a RequestRejectedException:

@Bean
public RequestRejectedHandler requestRejectedHandler() {
   return new HttpStatusRequestRejectedHandler();
}

Note that the default HTTP status code when using a HttpStatusRequestRejectedHandler is 400. However, we can customize this by passing a status code in the constructor of the HttpStatusRequestRejectedHandler class.

Now, let’s reconfigure the StrictHttpFirewall to allow \\ in the URL and HTTP GET, POST, DELETE, and OPTIONS methods:

strictHttpFirewall.setAllowBackSlash(true);
strictHttpFirewall.setAllowedHttpMethods(Arrays.asList("GET","POST","DELETE", "OPTIONS")

Next, invoke the API:

curl -i --user user:password -d @request.json -H "Content-Type: application/json" 
     -H "Accept: application/json" http://localhost:8080/api\\v1/users

And here we have a response:

{
  "code":201,
  "message":"User created successfully",
  "timestamp":1632812660569
}

Finally, let’s revert to the original strict functionality of StrictHttpFirewall by deleting the @Bean declaration.

Next, let’s try to invoke our API with suspicious URLs:

curl -i --user user:password -d @request.json -H "Content-Type: application/json" 
      -H "Accept: application/json" http://localhost:8080/api/v1//users
curl -i --user user:password -d @request.json -H "Content-Type: application/json" 
      -H "Accept: application/json" http://localhost:8080/api/v1\\users

Straightaway, all the above requests fail with error log:

org.springframework.security.web.firewall.RequestRejectedException: 
The request was rejected because the URL contained a potentially malicious String "//"

9. Conclusion

This article explains Spring Security’s protection against malicious URLs that may cause the Path Traversal/Directory Traversal attacks.

DefaultHttpFirewall tries to normalize the malicious URLs. However, StrictHttpFirewall rejects the requests with a RequestRejectedException. Along with Path Traversal attacks, StrictHttpFirewall protects us from several other attacks. Hence it is highly recommended to use the StrictHttpFirewall along with its default configurations.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LSS – NPI (cat=Security/Spring Security)
announcement - icon

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)
1 Comment
Oldest
Newest
Inline Feedbacks
View all comments