Protect your form redirect in Craft 2 and Craft 3 by hashing your redirect form data.
Back in version 2.6.2945 of Craft 2, Pixel & Tonic introduced the ability to require hashing of the redirect parameters that are set in forms (like when you sign in or sign up).
They introduced this enhancement to make Craft more secure. There is a potential Denial of Service (DoS) security issue with in-the-clear form data. In the example of a redirect parameter, this could allow someone to redirect the user to something other than what is specified in the hidden form element.
We need to protect our form data. Let’s learn how to do that, starting with Craft 2.
The solution to protecting the redirect parameter in Craft 2 is two-fold:
hash
filter, which takes the input and hashes it using a HMAC (Hashed Message Authentication Code). On the back-end, while processing the request, the developer can validate the hash using a validateData
method.redirect
parameter to be hashed. This new config setting is called validateUnsafeRequestParams
and it takes a boolean value. When set to true
then the unsafe parameters (which is just the redirect
parameter and perhaps some third party plugin parameters). Together, these will protect your form redirect parameter from any security issues.
Let’s use the login form as an example:
<form method="post" accept-charset="UTF-8">
{{ getCsrfInput() }}
<input type="hidden" name="action" value="users/login">
<input type="hidden" name="redirect" value="{{ '/profile' | hash}}">
<h3><label for="loginName">Username or email</label></h3>
<input id="loginName" type="text" name="loginName"
value="{{ craft.session.rememberedUsername }}">
<h3><label for="password">Password</label></h3>
<input id="password" type="password" name="password">
<label>
<input type="checkbox" name="rememberMe" value="1">
Remember me
</label>
<input type="submit" value="Login">
</form>
We have our standard hidden field with the redirect
name and the value is populated with a Twig output tag, a string for our redirect location. We use the hash
filter on the string to hash it.
If we load this in the browser we should see that the string is hashed:
<input type="hidden" name="redirect" value="58c6ace5c2af26ac04772d20aea67659590b9441/profile">
Now, we need to require all redirect parameters to be hashed using the config option.
In our craft/config/general.php
file we add the following item:
'validateUnsafeRequestParams' => true,
And now when we go to submit our form, it’ll validate the hash we pass as the redirect parameter and process the request.
If for some reason we have this enabled but we don’t hash our redirect parameter, Craft will return a error.
Protect the redirect parameter in Craft 3 is a simpler process because Craft 3 requires hashing of all redirect parameters. The validateUnsafeRequestParams
config setting we have in Craft 2 is gone. You can’t opt in (and you can’t opt out).
The only step we need to do in Craft 3 is to set our redirect
hidden field in the form we’re using and pass it through the hash
filter.
<input type="hidden" name="redirect" value="{{ '/profile' | hash}}">
And what happens in Craft 3 if don’t hash the redirect parameter?
In the case of the login form, the login routine will proceed (successful if the username and password are correct) but the redirect will fail. The value of the redirect parameter will not be honored.
Whether we are using Craft 2 or 3, we should be hashing the redirect parameters. It’s a good security practice in Craft 2 and by doing so you’ll be making your sites even more ready for a Craft 3 upgrade.