In this post, we present what a cookie tampering attack is and how Azion’s Signed Cookies solution can be used to prevent this attack from running in your applications.
How Do Cookie Tampering Attacks Work?
Cookie tampering is a type of attack in which a malicious agent alters client-side session cookie data to perform session theft, identity theft, and many other malicious actions.
This kind of attack happens when the web application uses cookie values in “plain text”—that is, without any type of encryption or any validation on the server side—to store session data that can give access to the restricted content of a given user.
How Can I Use Azion’s Signed Cookies Solution to Prevent Cookie Tampering Attacks Directly at the Edge?
Imagine the following scenario: after the user logs in to an application, it stores the user’s identifier in a cookie to use it in future requests.
Here we have an unprotected cookie, which is easy to manipulate.
And once manipulated, it’s possible to hijack the session and access the data of another user, Jose for example, as you can see below.
In this scenario, if we don’t have any security features to protect our session cookie from client-side manipulation, our application would be exposed and one user would have access to another user’s data through simple cookie manipulation.
Step #1 - Activate Solutions on Azion Marketplace
Go to console.azion.com/marketplace and search for “Signed Cookies”. You will find two edge functions: “Signed Cookies - Hash Generator” and “Signed Cookies - Hash Validator”. Both are necessary to protect your application against cookie tampering attacks.
To be able to use both edge functions, you need to have Edge Functions and Application Acceleration solutions active in your account.
Thus, both must be downloaded on our Marketplace. It’s very simple! Just click on the “Get it now”, as shown below.
Step #2 - Create New Instances of the Edge Functions Acquired in Your edge application
First, if your edge application still doesn’t have the Application Acceleration and Edge Functions modules active, you must activate them in the Main Settings tab. Check out how easy it is:
Once this is done, the next step is to create an instance of the “Signed Cookie - Hash Generator” function. This function will be responsible for creating signed cookies in our application. The JSON Args of this function has the following format:
{
"cookie_list": [],
"cookie_secret": "",
"tampering_cookie_prefix": "",
}
The “cookie_list” field is an array of strings, where we can define which cookies we want to subscribe to. In the case of our test application, we want to protect the “user” cookie, so the “cookie_list” value should be [“user”].
The “cookie_secret” field defines a password for encryption of the signed cookie, and here you can define any string.
The “tampering_cookie_prefix” field defines the prefix used to name the signed cookie. For example, if we use the value “sgnck”, the resulting signed cookie for our application would be “sgnck_user”.
So the JSON Args should look like this:
The next step is to create a new instance of the “Signed Cookie - Hash Validator” function, which will be responsible for validating that the signed cookies have not been modified on the client side. The JSON Args of this function has the following format:
{
"cookie_list": [],
"cookie_secret": "",
"tampering_cookie_prefix": "",
"tampering_violation_header_prefix": ""
}
The “cookie_list” field defines which cookies we want to validate the signature for.
The “cookie_secret” field defines a password for encryption of cookies sent by the client. Note that the cookie_secret must be equal to the value used in the signed cookie generation function, otherwise the validation will fail.
The “tampering_cookie_prefix” field defines the prefix used to name the signed cookies that were generated by the “Signed Cookie - Hash Generator” function. Note that here we must also use the same values as those used in the signed cookies generation function, otherwise the validation will also fail.
The “tampering_violation_header_prefix” field defines a prefix for the headers that will be added in the request, in case the function identifies any nonconformity in the cookies sent by the client.
After following these steps, the JSON Args should look like this:
Step #3 - Add the Instances Created in Rules Engine
Once the instances are created, the next step is to use them in the Rules Engine of our Edge Application.
First, we will need to create a rule in the Request Phase so that our Edge Application executes the “Forward Cookies” behavior—without it we won’t be able to generate the signed cookies.
This criteria in the screenshot above is merely illustrative, and you can adapt it to your application’s individual needs. The only requirement is that it is compatible with the criteria used to perform the Signed Cookies functions that we will create below.
Next, we must create a Response Phase rule to execute the “Signed Cookies - Hash Generator” function.
Thus, every time our application’s origin returns a Set Cookie header that includes a protected cookie, our edge function will create new signed cookies for each of the protected cookies.
In the example the origin responds a set-cookie for the “user” cookie, causing the edge function to create the “<prefix>_user” cookie</prefix>
However, we aren’t yet validating these cookies. To make it happen, the next step is to create a Request Phase function to execute the “Signed Cookies - Hash Validator” function.
At this point, the Rules Engine should look like this:
With this, our application starts to validate cookie manipulations on the front end. Notice how new request headers are added to our request when cookies values are changed on the client side.
When the cookie validation function identifies a violation, new headers are added to the request. The “<prefix>-Any” is set to “true” whenever any violation is identified. The “<prefix>-Counter” counts how many violations occurred on the request in question. The “<prefix>-List” receives a string with the name of all violated cookies (the names are separated by a comma if there is more than one cookie). Furthermore, for each violated cookie, a header of the same name with the value “violation” is added, as in the case of our test application, where the header “user” with the value “violation” was included.</prefix></prefix></prefix>
But so far, we haven’t taken any action in our edge application to prevent any cookie violations from happening–and that takes us to our next and final step.
Step #4 - Take Action to Identify Cookie Violation
To effectively block a cookie tampering attack, we need to define an action for our edge application to take when we identify a cookie violation.
Since our validation function adds headers at the moment a cookie violation happens, we can, for instance, execute a Deny behavior to prevent a user from using the cookie tampering technique to access our application.
For this, we can use one of the headers created by the “Signed Cookies - Hash Validator” function as a criteria of a Request Phase rule for the execution of Deny behavior.
Thus, when any user violates any protected cookie in our application, they will receive a static response with status code 403 directly from Azion’s edge locations, without even reaching the origin.
In the example, you can see the cookies originally delivered by the edge application to the user.
Here, the user tries to carry out a cookie tampering attack.
Next, the edge application identifies cookie violation and returns a static response to the user.
Done! Now our application is protected against cookie changes on the client side!
In the previous example, we used Deny behavior to prevent the user from accessing our application, but you can also use any other features that Azion offers, such as redirecting, setting a different origin, or choosing countless other possibilities!
Click here and secure your edge applications now!
And more: if you’re not at the edge yet, you get $300 in service credits to use on our platform.