Skip to main content
Build Custom Fiddler Extensions with C#
Advanced Techniques7 min read

Build Custom Fiddler Extensions with C#

Learn how to write production-ready Fiddler extensions in C# — from context menus and inspectors to HTTPS decryption handling and auto-responder rules.

Share:

Fiddler is more than a passive HTTP debugging proxy — it’s a programmable platform for deep network inspection, automation, and protocol analysis. When built-in features fall short — whether you're automating API regression tests, injecting custom headers for auth simulation, or building domain-specific inspectors for gRPC-Web traffic — writing a custom Fiddler extension in C# unlocks unprecedented control over the HTTP debugging workflow.

This tutorial walks you through creating production-ready Fiddler extensions from scratch: setting up your dev environment, implementing core interfaces like IFiddlerExtension and IContextMenu, adding custom inspectors and auto-responder rules, and safely handling HTTPS decryption in your logic. You’ll ship a working extension that logs request timing metrics to a file — a pattern easily extended to security auditing, performance baselining, or integration with CI pipelines.

Prerequisites and Environment Setup

Before writing code, ensure your Fiddler environment supports extension development:

  • Fiddler Classic (v5.0.20234.59130 or later) — not Fiddler Everywhere, which uses a different extensibility model.
  • Visual Studio 2022 (Community or higher) or VS Code with C# support.
  • .NET Framework 4.7.2+ — Fiddler Classic runs on .NET Framework, not .NET Core/.NET 5+.
  • FiddlerCore.dll — Automatically installed with Fiddler Classic; locate it at %LOCALAPPDATA%\Programs\Fiddler\FiddlerCore.dll.

Create a new Class Library (.NET Framework) project. Target .NET Framework 4.7.2. Then add a reference to FiddlerCore.dll. Right-click your project → Add ReferenceBrowse → navigate to the DLL path above.

Also add references to:

  • System.Windows.Forms (for UI dialogs)
  • System.Drawing (for icon resources, if used)
  • System.IO (for logging examples)

Finally, set your project’s Output Path to Fiddler’s Extensions folder: C:\Users\<user>\Documents\Fiddler2\Extensions\. This lets Fiddler auto-load your assembly on startup.

💡 Tip: Enable Tools > Fiddler Options > Extensions > Automatically load extensions on startup. Restart Fiddler after deployment to verify auto-loading.

Implementing IFiddlerExtension: Lifecycle and Registration

Every Fiddler extension must implement IFiddlerExtension, the entry point interface defined in FiddlerCore.dll. It exposes two methods:

  • OnLoad() — called when Fiddler loads your assembly. Use this to register event handlers, initialize state, or inject UI elements.
  • OnDispose() — called on shutdown. Clean up timers, file handles, or event subscriptions here.

Here’s a minimal implementation:

using Fiddler;

public class TimingLoggerExtension : IFiddlerExtension
{
    public void OnLoad()
    {
        // Subscribe to session completion events
        FiddlerApplication.AfterSessionComplete += OnAfterSessionComplete;
        
        // Optional: Register a custom menu item
        Utilities.WriteToLog("TimingLoggerExtension loaded.");
    }

    public void OnDispose()
    {
        FiddlerApplication.AfterSessionComplete -= OnAfterSessionComplete;
        Utilities.WriteToLog("TimingLoggerExtension unloaded.");
    }

    private void OnAfterSessionComplete(Session oSession)
    {
        // Your logic here
    }
}

Note the use of Utilities.WriteToLog() — a safe, thread-aware alternative to Console.WriteLine() inside Fiddler’s multithreaded pipeline.

Adding Context Menu Items with IContextMenu

Fiddler’s right-click context menus are highly extensible via IContextMenu. To add a "Log Timing" option visible only on HTTP requests:

public class TimingLoggerExtension : IFiddlerExtension, IContextMenu
{
    // ... OnLoad/OnDispose as before ...

    public string[] ContextMenuText => new[] { "Log Timing Info" };

    public bool[] IsEnabledForSession => new[] { true }; // Always enabled

    public void DoAction(string sCommand, Session[] arrSessions)
    {
        foreach (Session oSession in arrSessions)
        {
            var elapsed = oSession.Timers.ClientDoneResponse - oSession.Timers.ClientBeginRequest;
            string logLine = $"[{DateTime.Now:HH:mm:ss}] {oSession.fullUrl} → {elapsed.TotalMilliseconds:F1}ms\n";
            File.AppendAllText(@"C:\temp\fiddler-timing.log", logLine);
        }
    }
}

Now right-click any session in the Web Sessions list → select Log Timing Info, and your timing data appears in C:\temp\fiddler-timing.log.

✅ Pro tip: Use arrSessions.Length > 1 to enable batch operations. Add IsEnabledForSession[i] = arrSessions[i].oRequest.headers.Exists("X-Debug") to conditionally show the menu only for flagged requests — ideal for targeted fiddler debugging scenarios.

Building a Custom Inspector Tab

Inspectors let users view and edit raw or parsed HTTP messages. To build a simple "Timing Inspector" tab that displays latency breakdowns:

  1. Create a Windows Forms UserControl named TimingInspector.cs.
  2. Add labels for Client → Server, Server Processing, and Server → Client.
  3. Implement IInspector2:
public partial class TimingInspector : UserControl, IInspector2
{
    private Session _currentSession;

    public TimingInspector() => InitializeComponent();

    public void AssignSession(Session oSession)
    {
        _currentSession = oSession;
        UpdateUI();
    }

    public void Clear() => _currentSession = null;

    public bool IsReadOnly => true;

    public string GetSummary() => "Timing Breakdown";

    public string TabName => "Timing";

    public Control Control => this;

    private void UpdateUI()
    {
        if (_currentSession == null) return;

        var t = _currentSession.Timers;
        labelClientToServer.Text = $"{t.ClientBeginRequest → t.ServerBeginRequest}: {(t.ServerBeginRequest - t.ClientBeginRequest).TotalMilliseconds:F1}ms";
        labelServerProcessing.Text = $"{t.ServerBeginRequest → t.ServerDoneResponse}: {(t.ServerDoneResponse - t.ServerBeginRequest).TotalMilliseconds:F1}ms";
        labelServerToClient.Text = $"{t.ServerDoneResponse → t.ClientDoneResponse}: {(t.ClientDoneResponse - t.ServerDoneResponse).TotalMilliseconds:F1}ms";
    }
}

Then register it in OnLoad():

FiddlerApplication.UI.AddInspector("Timing", typeof(TimingInspector));

Now click any session → switch to the Timing tab in the bottom inspector panel. This is especially valuable during fiddler debugging of slow APIs or misbehaving CDNs.

Handling HTTPS Decryption Safely

Custom extensions often need to read or modify encrypted traffic — but HTTPS decryption requires explicit opt-in and carries security implications. Never assume decrypted content is available.

Always check:

if (oSession.oRequest.pipeClient != null && oSession.oRequest.pipeClient.IsEncrypted)
{
    // Content is still encrypted — skip parsing
    return;
}

More robustly, use Fiddler’s built-in decryption readiness check:

if (!oSession.bHasResponse || !oSession.oResponse.headers.Exists("Content-Type"))
    return;

// Only proceed if response body is decrypted and accessible
if (oSession.ResponseBody == null || oSession.oResponse.bodyBytes == null)
    return;

Remember: HTTPS decryption in Fiddler relies on its root certificate being trusted system-wide. If users haven’t run Tools > Options > HTTPS > Decrypt HTTPS traffic, your extension will see empty bodies — a common cause of silent failures. Log warnings using Utilities.WriteToLog() to aid troubleshooting during http debugging.

Packaging, Distribution, and Debugging Tips

Build & Deploy Workflow

  • Set Copy to Output Directory = Copy always on your .dll in Visual Studio.
  • Use Post-build event to auto-copy: copy "$(TargetPath)" "C:\Users\$(USERNAME)\Documents\Fiddler2\Extensions\"
  • After rebuilding, reload extensions via Help > Reload Extensions — no Fiddler restart needed.

Debugging Strategies

  • Attach Visual Studio debugger to Fiddler.exe (Debug > Attach to Process) before triggering your extension logic.
  • Wrap critical sections in try/catch and log exceptions — unhandled exceptions crash Fiddler silently.
  • Avoid long-running synchronous I/O (e.g., File.WriteAllText) on the main thread. Offload to Task.Run() or use async file APIs where possible.

Versioning & Compatibility

  • Check FiddlerApplication.Version at runtime to guard against breaking changes.
  • Avoid referencing unstable internal Fiddler types (Fiddler.HTTP...). Stick to documented interfaces: Session, IFiddlerExtension, IInspector2, IAutoResponderRule.

Bonus: Auto-Responder Rule Integration

You can also extend Fiddler’s AutoResponder with custom logic. Implement IAutoResponderRule to match sessions by custom criteria (e.g., query param presence + header value) and return dynamic responses:

public class MockAuthRule : IAutoResponderRule
{
    public bool ShouldRespond(Session oSession) =>
        oSession.url.Contains("/api/auth") &&
        oSession.oRequest.headers.Exists("X-Test-Mode");

    public ResponseHeaders GetResponseHeaders() => new ResponseHeaders
    {
        ["Content-Type"] = "application/json",
        ["X-Fiddler-Injected"] = "true"
    };

    public byte[] GetResponseBody() => Encoding.UTF8.GetBytes(
        "{\"status\":\"mocked\",\"token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"}");
}

Register in OnLoad() with FiddlerApplication.AutoResponder.AddRule(new MockAuthRule());. This integrates seamlessly into Fiddler’s existing fiddler proxy behavior — no UI changes required.

Conclusion and Key Takeaways

Writing custom Fiddler extensions transforms Fiddler from a diagnostic viewer into a programmable HTTP debugging platform. With just a few interfaces — IFiddlerExtension, IContextMenu, IInspector2, and IAutoResponderRule — you gain full access to every stage of the request-response lifecycle, including secure HTTPS traffic (when properly configured).

Key lessons:

  • Always handle HTTPS decryption defensively — never assume ResponseBody is populated.
  • Prefer Utilities.WriteToLog() over Console.WriteLine() for reliable logging.
  • Clean up event subscriptions in OnDispose() to prevent memory leaks.
  • Use context menus and inspectors to expose functionality without cluttering the UI.
  • Test extensions across Fiddler versions and under varying HTTPS decryption states.

Whether you’re building internal tooling for your QA team, extending https decryption workflows, or integrating Fiddler into automated API testing suites, these patterns scale reliably. For more powerful integrations — like scripting with JScript.NET or building hybrid extensions with embedded web UIs — explore our more tutorials section.

Ready to go deeper? Browse Advanced Techniques tutorials for guides on FiddlerCore headless mode, TLS fingerprinting detection, and real-time WebSocket inspection. Or contact us if you need help architecting enterprise-grade extensions.

Share:

Related Topics

fiddler tutorialfiddler debugginghttp debuggingfiddler proxyhttps decryption

Get Fiddler Tips & Tutorials

Stay updated with the latest Fiddler tutorials, HTTP debugging guides, request modification tips, and web traffic analysis techniques.

Free forever. New tutorials published daily.

Related Articles