Debugging ASP.NET 2.0 Web Resources: Decrypting the URL and Getting the Resource Name

by ASP.NET AJAX Team | Comments 10

Today I had another trivial problem that was unbelievably hard to debug just because I could not tell that an error caused by a web resource was caused by exactly that resource. I was dealing with a forgotten [WebResource] attribute that did not have a matching resource built in the assembly and both generated a server side exception and gave browsers a 404 HTTP error.

I wanted to decrypt the query string data that was being passed to WebResource.axd and extract the resource and assembly name from it. MSDN told me that what I needed was the "d" query string parameter, as it contained the encrypted assembly and resource name. The "t" attribute is the assembly time stamp, it is there, so that we have a different URL when we upgrade the assembly and our clients do not cache and use the old web resources.

Back to decrypting that string. I noticed that it was being encrypted using the MachineKeySection.EncryptOrDecryptData() method, so we can easily decrypt that. Unfortunately, the method is declared internal. That should not be allowed to stop us, should it? Here goes the code:

=======================================

        byte[] encryptedData = HttpServerUtility.UrlTokenDecode(urlEncodedData);

        Type machineKeySection = typeof(MachineKeySection);
        Type[] paramTypes = new Type[] { typeof(bool), typeof(byte[]), typeof(byte[]), typeof(int), typeof(int) };
        MethodInfo encryptOrDecryptData = machineKeySection.GetMethod("EncryptOrDecryptData", BindingFlags.Static | BindingFlags.NonPublic, null, paramTypes, null);

        try
        {
            byte[] decryptedData = (byte[])encryptOrDecryptData.Invoke(null, new object[] { false, encryptedData, null, 0, encryptedData.Length });
            string decrypted = Encoding.UTF8.GetString(decryptedData);

            decryptedLabel.BackColor = Color.Lime;
            decryptedLabel.Text = decrypted;
        }
        catch (TargetInvocationException)
        {
            decryptedLabel.BackColor = Color.Red;
            decryptedLabel.Text = "Error decrypting data. Are you running your page on the same server and inside the same application as the web resource URL that was generated?";
        }

=======================================

The tricky part is that we use the MachineKeySection class to do our job and we deal with encryption settings specific to the current application. This means that decrypting web resource URL will work if and only if you run the code on the same server and from the same web application that generated the resource.

I am attaching a standalone page that you can drop in your application’s root and request it. You can then paste a web resource URL in the text box and decrypt it. You can even drop controls on the page and the dropdown will be automatically filled with all registered scripts and stylesheets served from web resources. Happy hacking!

About the author

Stefan Rahnev

Stefan Rahnev

is the Unit Manager of the ASP.NET Telerik Division. He has been working for the company since 2005, when he started out as a regular support officer. His next steps at Telerik took him through the positions of Technical Support Director and co-team leader in one of the ASP.NET AJAX teams. Stefan’s main interests are web development, agile processes planning and management, client services and psychology.

10 Comments

Ghost
This saved my day!  Thanks for posting this very helpful .aspx.
Chris
Very useful page, thanks for offering it for download.
Al
When I try to input my encoded value for 'd' I get the following exception: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. 
What am I doing wrong?
Thanks
RK
I get the same error as Al.  Any idea?
rob
The same error here!
Radoslav Kirilov
I have tried it on my side and it works as expected. Here I have attached a small video which demonstrates that. 

What kind of resources did you try to decode?
PAolo De Poi
Great! It solved my problem, thanks a lot!
CI
The same error here :-(
Tim Harker
Will it work with an HTTPS url?
Radoslav Kirilov
Yes, the provided example works with HTTPS urls. On the following link I attached a small video which demonstrates it.

Comments

  1.    
      
      
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)
Read more articles by ASP.NET AJAX Team - or - read latest articles in Developer Tools