Search code examples
c#sslfiddlerfiddlercore

SSL received a record that exceeded the maximum permissible length when modifying request with fiddler


I'm trying to implement a in-system SSL server using FiddlerCore:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace fiddlerCoreTest
{
    using System.IO;
    using System.Threading;
    using Fiddler;

    class Program
    {
        static Proxy oSecureEndpoint;
        static string sSecureEndpointHostname = "localhost";
        static int iSecureEndpointPort = 7777;

        static void Main(string[] args)
        {
            //var tt = Fiddler.CertMaker.GetRootCertificate().GetRawCertData();
            //File.WriteAllBytes("root.crt",tt);

            Fiddler.FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
            {
                oS.bBufferResponse = false;               

                if ((oS.hostname == sSecureEndpointHostname)&&oS.port==7777)
                {
                    oS.utilCreateResponseAndBypassServer();
                    oS.oResponse.headers.HTTPResponseStatus = "200 Ok";
                    oS.oResponse["Content-Type"] = "text/html; charset=UTF-8";
                    oS.oResponse["Cache-Control"] = "private, max-age=0";
                    oS.utilSetResponseBody("<html><body>Request for httpS://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString());
                }
            };

            FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
            oFCSF = (oFCSF & ~FiddlerCoreStartupFlags.RegisterAsSystemProxy);

            Fiddler.FiddlerApplication.Startup(8877, oFCSF);

            oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, sSecureEndpointHostname);
            if (null != oSecureEndpoint)
            {
                FiddlerApplication.Log.LogFormat("Created secure end point listening on port {0}, using a HTTPS certificate for '{1}'", iSecureEndpointPort, sSecureEndpointHostname);
            }

            Console.WriteLine("Press any key to exit");

            Console.ReadKey();
        }
    }
}

in firefox, GET http://localhost:7777/ works fine, but when I GET https://localhost:7777/ , firefox reports following error:

SSL received a record that exceeded the maximum permissible length

Why do I get this, and how can I fix it?

UPDATE This happens only when I use fiddler as the proxy with firefox. When I remove fiddler proxy, I can access https://localhost:7777/ . However, I would also like to be able to access https://localhost:7777/ via proxy


Solution

  • The problem in this scenario is that you're processing this traffic twice:

    First, the browser sends a CONNECT to port 8888 saying: "Please give me a TCP/IP tunnel to port 7777" and then after Fiddler says "Okay, we'll do that" the client sends a HTTPS request through that tunnel to port 7777.

    The problem here is that you're mangling that CONNECT response and returning HTML instead of allowing the HTTPS handshake from port 7777 to flow through.

    The simplest way to fix this would be to change your BeforeRequest code to the following:

    if ( (oS.hostname == sSecureEndpointHostname) && (oS.port==7777)
        && !oS.HTTPMethodIs("CONNECT")) {
    

    After you do this, your CONNECT tunnel will no longer be getting mangled and the HTTPS handshake will succeed.