2

I would like to change the logic of the image hashing. Because our width and height parameters directly in the url. As I checked the HashingUtils class it does not look to easy to change without any risk because it can be used any other assemblies and I already found 3 places where it is used in the Sitecore.Kernel assembly. The problem is that the default implementation only deal with querystring parameters.

For example the url should like this:

/images/{22EB368A-4AD3-48C8-B1EB-1BC14DE0F7BF}-200-100.jpg?hash=AE8EB10933E68E98C9C65324F9CDF0FA2D3AEBAA

And I would like to generate the hash from the part of the url. In this case from 200 and 100.

I already implemented a custom MediaProvider which is resolving the media item by ID, width and height. Actually the resolving done by a composite key [ID]-[width]-[height].

  • Can you explain your problem more detailed. Probably by adding a url example of what it is now and what you would like it to be – phani Dec 9 '16 at 13:36
  • Crossing the river to get water. The width and height parameters are exactly the reason hashing is done to begin with - to prevent DOS attacks by creating a million differently scaled versions of images in your media cache. – Mark Cassidy Dec 9 '16 at 13:43
  • @MarkCassidy true. That's why I want to generate the hash from the width and height. The only difference is that these parameters are not in the querystring, they are part of the path. – Tamás Tárnok Dec 9 '16 at 13:46
  • I don't get it then. If you make them part of the path, they become publicly accessible. No? – Mark Cassidy Dec 9 '16 at 13:52
  • 1
    UPDATE: Turns out the HashingUtils::ComputeHash() method @Dmytro mentions below already includes a salt that is stored in the Sitecore setting Settings.Media.RequestProtection.SharedSecret, so that should be sufficient, assuming you remembered to change it from its default value. – Richard Hauer Dec 9 '16 at 23:49
5

Solution

HashingUtils.ProtectAssetUrl(string url) and HashingUtils.GetAssetUrlHash(string url) take the full URL path into account when generating the hash. So there are no adjustments in the algorithm that you need to make.

Just use this code:

string imageUrl = // get the URL
imageUrl = HashingUtils.ProtectAssetUrl(imageUrl);

This is all you need to generate a URL with an added hash value.


Proof

Here's the (reformatted) source code of HashingUtils.GetAssetUrlHash():

public static string GetAssetUrlHash(string url)
{
    url = url.ToLowerInvariant();

    UrlString urlString = new UrlString(url);

    if (!HashingUtils.Proxy.IsMediaUrl(url))
    {
        return string.Empty;
    }

    Uri result;
    string urlPath = (Uri.TryCreate(url, UriKind.Absolute, out result) ? result.LocalPath : urlString.Path).TrimStart('/');

    StringBuilder stringBuilder = new StringBuilder();

    stringBuilder.Append(string.Format("{0}?", urlPath));

    for (int i = 0; i < MediaManager.Config.RequestProtection.QueryParametersToProtect.Count; i++)
    {
        stringBuilder.Append(
            string.Format(
                "{0}={1}",
                MediaManager.Config.RequestProtection.QueryParametersToProtect[i],
                urlString.Parameters[MediaManager.Config.RequestProtection.QueryParametersToProtect[i]]));

        if (i < MediaManager.Config.RequestProtection.QueryParametersToProtect.Count - 1)
        {
            stringBuilder.Append("&");
        }
    }

    return HashingUtils.ComputeHash(stringBuilder.ToString());
}

As you can see, the URL path is used when creating the hash. It's appended to the stringBuilder:

stringBuilder.Append(string.Format("{0}?", urlPath));

The urlPath here will be equal to /images/{22EB368A-4AD3-48C8-B1EB-1BC14DE0F7BF}-200-100.jpg in your example.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.