The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

Hashing Redirect Params in Craft

by Ryan Irelan

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.

Protecting Return Parameters in Craft 2

The solution to protecting the redirect parameter in Craft 2 is two-fold:

  • In Craft 2.5.2750, the developers introduced the 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.
  • In Craft 2.6.2945. the developers introduced a configuration setting that forced each request with a 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">

        <input type="checkbox" name="rememberMe" value="1">
        Remember me

    <input type="submit" value="Login">

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.

Protecting Redirect Parameters in Craft 3

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.

The Takeaway

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.

Filed Under: Craft CMS, Free Tutorials