In my previous blog post, I had discussed about Cross-site Request Forgery, how it happens. I had mentioned about a couple of preventative measures that web application developers could follow to provide a safe and better experience to their users.
The basic flow of events in a normal “secure” client-server request-response would go as follows. Client types in his/her credentials and clicks Sign In, which sends a POST request to the server. The server would check if the username and password matches with what’s there in its storage. If the user is a match, server would generate a session cookie, store it against the username and send it back in the response header as set-cookie=abc123. The client browser would then store this session cookie in the cookie storage and send it along any subsequent requests made to the server. The issue with this is any malicious party could trick the authenticated user externally to send in a request on behalf of the attacker unbeknownst to the user. In this post, we shall take a look at the Synchronizer Token Pattern and a quick example application which implements this pattern.
Flow of Events of Synchronizer Token Pattern
Flow of events
Why is this secure?
Of course still a malicious entity could do some social engineering and manipulate the the user into clicking or executing a state-changing operation from the client browser unbeknownst to the user. The attacker could easily forge a similar form with all hidden fields and execute the url from the user’s browser… and that server’s relevant session cookie would be sent along the request too. But the request would fail on the server side. The reason is that the the token embedding cannot be carried out by the attacker because cross-domain AJAX calls are blocked by default.
This sample application is implemented using Spring Boot.
Below is the login page, which uses Thymeleaf for as the templating engine.
The login action submits the credentials to the server. I don’t want to go deep on how Thymeleaf handles the data binding (it’s a topic for another time).
Next up we shall take a look at the Main Controller which for simplicity’s sake would handle our Login post request and the subsequent state changing post request to add a blog post.
Next up we’ll look at the Service class which processes the requests, i.e. validate user, validate session, validate token and so on.
Once the user submits the form, it gets sent to the post end-point and in the request body is the form fields which contains the hidden field witht the token value. How the “synchronizer” validation is done in the server is also available in the gist above “MainController.java”. Upon receiving the request the server will validate the token from the body.
The full implementation of this pattern can be found in this GitHub link.
In the next blog, we shall look at how the Double Submit Cookie pattern works and its implications.
If you enjoyed this article, please hold down the clap button below 👏 to help others find it.