me

Using Fiddler to emancipate HttpOnly cookies for web app debugging

Posted on 10/01/2013

Cookie Monster meme ftw In light of the hybrid native app developer's Declaration of Independence, this post might very well be the first shot of the revolution.

Problem: Debugging in a browser

This post applies to you if:

  1. You are building some sort of native application based on HTML and JavaScript (PhoneGap in my case)
  2. You are working with a web service that you don't control, and it uses HttpOnly cookies
  3. Your application requires the values of said cookies to work (most likely related to the authentication pipeline)
  4. You have come to terms with this reality and you're using native web libraries to work around this fact
  5. You are no longer able to run and debug your application in a browser because of #4, and now you feel like you've been tossed back about 20 years in the past of application development and maybe even you've resorted to using console.log for your debugging and feel defeated (I know I did!)

Solution: Proxy FTW!

In order to restore debugging support, we're going to need to sanitize the set-cookie HTTP header on it's way down to our application, and the easiest way to do this across all browsers is to use a proxy tool. The most popular tool for this type of operation is Fiddler, so this post will cover how to set this up in Fiddler. To best explain what we're doing here, here is a before and after view of a cookie that we need to work with.

Before:

Set-Cookie: Flavor=chocolatechip; secure; HttpOnly

After:

Set-Cookie: Flavor=chocolatechip;

 

For example, if you had your web application open from http://localhost/myapp, your page's JavaScript would now be able to access the Flavor cookie. So, super easy, right?  Following is my 3-step plan.

 

1: Install the syntax highlighting add-on bundle

This step is just to make things easier on you and is not required. 

syntax add-on download

Installing this add-on adds a tab to your Fiddler interface which gives you one-click access to the Fiddler Script custom rules:

FiddlerScript tab

2: Create a custom rule definition using FiddlerScript

To avoid going into too much detail here about how to create custom rules, see the official documentation and the Fiddler book site which have good examples. I will say that when you first crack open the rules file, you're immediately greeted with a couple of lines of code like this:

public static RulesOption("Hide 304s")
var m_Hide304s: boolean = false;

What is that var declaration with a colon and a type?  Well, good reader, that is likely the first and the last time you'll work with a language called JScript (also referred to as JScript.NET).  I've leave the speculation (or research) up to you on how JScript ended up being the language of choice for custom rules. Let's just say it's a bit out of the way to locate a good set of documentation on this language. Hopefully you'll find examples that accomplish everything you need for your custom rule requirements either through a search or in the example below.

Add the following 2 lines of code in the file and save it in order to create a new rule definition.

public static RulesOption("Free the Cookies!")
var m_FreeTheCookies: boolean = false;

You should now see the rule in the Rules menu. Clicking this item will enable it, so all that's left to do is add the code for the implementation. It's helpful to remember that your rule will need to be enabled every time you save the script file or close and reopen Fiddler (by default, at least).

Rules menu

3. Write the custom rule implementation

In order to sanitize the cookies, we need to add our implementation into the response handler method, OnBeforeResponse, which should already be in the default rules script.  Just add the following code to the bottom of the method.

if(m_FreeTheCookies) {

    for (var x:int = 0; x < oSession.oResponse.headers.Count(); x++) {

        if(oSession.oResponse.headers[x].Name.Contains("Set-Cookie")) {

            var cookie : Fiddler.HTTPHeaderItem = oSession.oResponse.headers[x];

            if(cookie.Value.Contains("HttpOnly") || cookie.Value.Contains("secure;")) {

                FiddlerObject.log("Liberation time! Cookie to free: " + cookie.Value);
            
                cookie.Value = cookie.Value.Replace("HttpOnly", String.Empty).Replace("secure;", String.Empty);
            }
        }                                
    }
}

After re-enabling the rule and accessing your favorite web service with HttpOnly cookies, you should be in business.

You can use FiddlerObject.log and the Log tab to confirm the rule is working:

Fiddler log

 

Hope this helps!

1 comment:

  1. Thanks for the post!

    One problem with your rule is that you're using the CONTAINS method, which is case-sensitive. You'll probably want to use the .indexOf() method with the StringComparison.OrdinalIgnoreCase flag.

    > I've leave the speculation (or research) up to you on how
    > JScript ended up being the language of choice for custom rules.

    The answer there is pretty simple: .NET only exposed JScript.NET and VBScript.NET as choices using the VSA engine, which is what Fiddler uses. A future update to Fiddler will allow use of C# as a "script" engine, although even today you can simply compile an IFiddlerExtension to use any .NET language you like to extend Fiddler.

    ReplyDelete