We have learned about how to use basic Spring Security and OAuth 2.0’s default security features for authentication and authorization. But we need to be able to resist additional attacks!
As a part of Spring Security’s default configuration, there is a mechanism to block CSRF (pronounced see-surf) attacks, one of the OWASP top ten security attacks.
Understanding CSRF Attacks
CSRF (Cross-Site Forgery Attacks) are prevalent in the world of malicious hacking, so it is best to include this protection on your web application. Mostly, this type of attack targets web applications with a cookie and token-based authentication.
What happens in a CSRF attack?
You know that the browser holds your session information in a cookie or a token. This token or cookie is used to keep you authenticated as you perform transactions. Sometimes due to adware or malware that ends up in your browser (and it’s not always your fault!), hackers can get access to your session cookies and tokens that are stored on your browser or your local machine. Having access to cookies and tokens means that the hacker can log in as you. They can do this by stealing your credential information from the session cookies.
Well, typically, when you are logged in with a token, it won’t allow easy access to your user credential like a session cookie does, but it is a way to store your session information on a browser. Now the hacker can’t use your credentials, but they can try to act as you by creating an HTTP request on your behalf!
Let’s say you transfer $100 to Patrick’s bank account. When this transaction is made, and you click the button to transfer the money, your browser sends an HTTP request to your bank. This request is sent through the network from your browser to the bank’s server. It can look something like this:
GET http://netbank.com/transfer.do?acct=Patrik&amount=$100 HTTP/1.1
Now, the hacker Ms. Haxx0r, decides she wants you to send $100 to her too, so she creates a similar request.
GET http://netbank.com/transfer.do?acct=Haxx0r&amount=$100 HTTP/1.1
Her problem is that the HTTP request needs to be sent from the browser and must be done by clicking on a button that sends that request like in the bank.
Here’s where social engineering comes in. Ms. Haxx0r is good at tricking users into giving her what she needs instead of spending the time to break into your computer through the network.
She creates an email that looks like it came from your boss. In the email, she says that you have an important article that you have to read, and gives you the hyperlink that looks like this: http://cnn.com/importantannouncement. You click on it, but it is actually her request. She stuck it in this way:
<a href="http://yourbank.com/transfer.do?acct=Haxxor&amount=$100"> http://cnn.com/importantannouncement</a>
Since you are still logged into your bank, the bad HTTP request gets sent via the network to the bank, as though it's a transaction you made.
Another way Ms. Haxx0r can get her $100 is to have access to your browser and use your token. If an unencrypted token sits in local storage or your browser, it is also going to allow her to take over your session because you are still logged on.
Luckily, Spring Security has some pretty neat tricks up its sleeve with the csrf()
method enabled by default on your client web application.
Use Spring Security to Prevent CSRF Attacks
Luckily, Spring Security has an excellent solution to preventing a CSRF attack from happening to a user of your Spring web application.
This answer is also twofold:
First, when you use the
logout()
method in your security filter chain, the token for your session expires, so the browser doesn’t save details that a malicious user can later exploit.Second, it creates a new token every time a banking transaction is made. Because of this, there is a validity check made to ensure that the
POST
request is valid and not some malicious code that is run in the background.
So how do we implement these amazing features?
Let’s start with the logout()
method. This method clears your session and invalidates the cookie in the browser, hence getting rid of any dynamic content the CSRF attacker can use. This method sends a POST
request with a CSRF token to ensure that it is a valid request.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.logout()
.invalidateHttpSession(true);
}
It’s important to note that Spring Security includes CSRF protection out of the box with the csrf()
method. If you want to enable/disable it to do your own custom security filter chain, do it in your security filter chain like this:
Enable CSRF
@Override
protected void configure(HttpSecurity http) throws Exception{
http.csrf();
}
Disable CSRF
@Override
protected void configure(HttpSecurity http) throws Exception{
http
.csrf().disable();
}
As you know, CSRF isn’t the only typical web application attack prevented by default in Spring Security. It is also not wholly hacker-free, so make sure and add this safeguard along with the other secure programming practices like OAuth 2.0 and OIDC.
You see, when the OAuth 2.0 authorization server sends the authorization code and the access token, they can be used by a malicious user in a CSRF attack. There are a few ways to prevent this:
Ensure you have a solid RedirectURI registered with your OAuth 2.0 IdP.
Add a CSRF token to your RedirectURI by using the
_csrf
attribute to obtain it.Add the CSRF token to all of your HTTP requests to include
GET
,POST
,DELETE
, etc. This is added by default when you use Spring Security with@EnableWebSecurity
in your security filter chain.
The code looks like this:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
method="post">
<input type="submit"
value="Log out" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
</form>
If you want to use a CSRF token in session cookies in your Java web app, you can use some default Angular configurations in Java by using the csrfTokenRepository class:
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http)throws Exception{
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
This will set your HttpOnly flag
to false
, which will end up transferring the security measures to your CSRF token.
Let's Recap!
CSRF (Cross-site forgery attacks) targets web applications with cookie and token-based authentication.
Spring Security uses the CSRF method by default.
When using OAuth, add a CSRF token to your RedirectURI as well as to all your HTTP requests.
In the next chapter, you will learn how Spring Security prevents your web applications from getting hijacked by leading unsuspecting users to random malicious websites by adding CORS protection!