コンテンツにスキップ

Fiddler Cheatsheet

- :material-content-copy: **[Copy to Clipboard](#copy-to-clipboard)** - :material-file-pdf-box: **[Download PDF](#download-pdf)**

Overview

Fiddler is a powerful web debugging proxy tool that captures HTTP and HTTPS traffic between your computer and the internet. It allows developers, testers, and security professionals to inspect, modify, and debug web traffic in real-time, making it an essential tool for web development, API testing, and security analysis.

Key Features

  • Traffic Capture: Monitor all HTTP/HTTPS traffic from any application
  • Request/Response Inspection: Detailed analysis of headers, bodies, and timing
  • Traffic Modification: Edit requests and responses on-the-fly
  • Performance Analysis: Identify bottlenecks and optimization opportunities
  • Security Testing: Analyze authentication, session management, and vulnerabilities
  • API Testing: Test and debug REST APIs and web services
  • Mobile Testing: Capture traffic from mobile devices and applications
  • Scripting Support: Automate tasks with JScript.NET and C# scripts

Installation

Fiddler Classic (Windows)

# Download from official website
# https://www.telerik.com/fiddler

# Silent installation
FiddlerSetup.exe /S

# Manual installation
# 1. Download installer
# 2. Run as administrator
# 3. Follow installation wizard
# 4. Configure proxy settings

# Verify installation
Get-Process | Where-Object {$_.ProcessName -eq "Fiddler"}

Fiddler Everywhere (Cross-platform)

# Download from official website
# https://www.telerik.com/fiddler/fiddler-everywhere

# Linux installation (AppImage)
wget https://downloads.getfiddler.com/linux/fiddler-everywhere-[VERSION].AppImage
chmod +x fiddler-everywhere-[VERSION].AppImage
./fiddler-everywhere-[VERSION].AppImage

# macOS installation
# Download .dmg file and install

# Windows installation
# Download .exe installer and run

Docker Installation

# Run Fiddler in Docker (unofficial)
docker run -d \
  --name fiddler-proxy \
  -p 8888:8888 \
  -p 8080:8080 \
  -v fiddler-data:/data \
  fiddler/proxy:latest

# Access web interface
# http://localhost:8080

Basic Configuration

Initial Setup

# Configure system proxy (Windows)
# Fiddler automatically configures system proxy on startup
# Default proxy: 127.0.0.1:8888

# Manual proxy configuration
# System Settings → Network → Proxy
# HTTP Proxy: 127.0.0.1:8888
# HTTPS Proxy: 127.0.0.1:8888

# Verify proxy configuration
netsh winhttp show proxy

HTTPS Decryption Setup

# Enable HTTPS decryption in Fiddler
# Tools → Options → HTTPS tab
# ✓ Capture HTTPS CONNECTs
# ✓ Decrypt HTTPS traffic

# Install Fiddler root certificate
# Actions → Trust Root Certificate
# This installs Fiddler's CA certificate

# Manual certificate installation (Windows)
certlm.msc
# Navigate to Trusted Root Certification Authorities
# Import FiddlerRoot.cer

# Export Fiddler certificate for other devices
# Tools → Options → HTTPS → Actions → Export Root Certificate to Desktop

Mobile Device Configuration

# Configure mobile device proxy
# Device Settings → Wi-Fi → Network → Proxy
# Manual proxy configuration:
# Server: [Fiddler-PC-IP-Address]
# Port: 8888

# Install certificate on mobile device
# Navigate to: http://[Fiddler-PC-IP]:8888
# Download and install FiddlerRoot.cer

# iOS certificate installation
# Settings → General → VPN & Device Management
# Install downloaded certificate
# Settings → General → About → Certificate Trust Settings
# Enable full trust for Fiddler certificate

# Android certificate installation
# Settings → Security → Install from storage
# Select FiddlerRoot.cer
# Name: Fiddler
# Use for: VPN and apps

Traffic Capture and Analysis

Basic Traffic Monitoring

// Fiddler Script (FiddlerScript.cs)
// Customize request/response handling

class Handlers
{
    // Before request is sent
    static function OnBeforeRequest(oSession: Session) {
        // Log all requests
        FiddlerApplication.Log.LogString("Request: " + oSession.fullUrl);

        // Filter specific domains
        if (oSession.HostnameIs("example.com")) {
            oSession["ui-color"] = "red";
            oSession["ui-bold"] = "true";
        }

        // Block specific requests
        if (oSession.uriContains("analytics")) {
            oSession.oResponse.headers.HTTPResponseCode = 404;
            oSession.oResponse.headers.HTTPResponseStatus = "404 Not Found";
            oSession.utilCreateResponseAndBypassServer();
        }
    }

    // After response is received
    static function OnBeforeResponse(oSession: Session) {
        // Log response details
        FiddlerApplication.Log.LogString("Response: " + oSession.responseCode + " " + oSession.fullUrl);

        // Modify response headers
        if (oSession.HostnameIs("api.example.com")) {
            oSession.oResponse.headers.Add("Access-Control-Allow-Origin", "*");
        }

        // Replace response content
        if (oSession.uriContains("/api/data")) {
            oSession.utilDecodeResponse();
            var responseBody = oSession.GetResponseBodyAsString();
            responseBody = responseBody.replace("old_value", "new_value");
            oSession.utilSetResponseBody(responseBody);
        }
    }
}

Advanced Filtering

// Custom filters in Fiddler
// View → Filters → Use Filters

// Filter by host
if (oSession.HostnameIs("api.example.com")) {
    oSession["ui-color"] = "blue";
}

// Filter by HTTP method
if (oSession.HTTPMethodIs("POST")) {
    oSession["ui-color"] = "green";
}

// Filter by response code
if (oSession.responseCode >= 400) {
    oSession["ui-color"] = "red";
    oSession["ui-bold"] = "true";
}

// Filter by content type
if (oSession.oResponse.headers.ExistsAndContains("Content-Type", "application/json")) {
    oSession["ui-color"] = "yellow";
}

// Filter by request size
if (oSession.requestBodyBytes.Length > 1024) {
    oSession["ui-color"] = "orange";
}

// Complex filtering logic
if (oSession.HostnameIs("secure.example.com") && 
    oSession.HTTPMethodIs("POST") && 
    oSession.uriContains("/login")) {
    oSession["ui-color"] = "purple";
    oSession["ui-bold"] = "true";
    FiddlerApplication.Log.LogString("Login attempt detected: " + oSession.fullUrl);
}

Request/Response Inspection

// Inspect request details
function InspectRequest(oSession) {
    // Request line
    var method = oSession.RequestMethod;
    var url = oSession.fullUrl;
    var httpVersion = oSession.oRequest.headers.HTTPVersion;

    // Request headers
    var headers = oSession.oRequest.headers;
    for (var i = 0; i < headers.Count(); i++) {
        var header = headers[i];
        FiddlerApplication.Log.LogString("Header: " + header.Name + " = " + header.Value);
    }

    // Request body
    var requestBody = oSession.GetRequestBodyAsString();
    if (requestBody.length > 0) {
        FiddlerApplication.Log.LogString("Request Body: " + requestBody);
    }

    // Query parameters
    var queryParams = oSession.oRequest.headers.RequestPath.split('?')[1];
    if (queryParams) {
        var params = queryParams.split('&');
        for (var j = 0; j < params.length; j++) {
            FiddlerApplication.Log.LogString("Query Param: " + params[j]);
        }
    }
}

// Inspect response details
function InspectResponse(oSession) {
    // Response status
    var statusCode = oSession.responseCode;
    var statusText = oSession.oResponse.headers.HTTPResponseStatus;

    // Response headers
    var headers = oSession.oResponse.headers;
    for (var i = 0; i < headers.Count(); i++) {
        var header = headers[i];
        FiddlerApplication.Log.LogString("Response Header: " + header.Name + " = " + header.Value);
    }

    // Response body
    oSession.utilDecodeResponse();
    var responseBody = oSession.GetResponseBodyAsString();
    FiddlerApplication.Log.LogString("Response Body Length: " + responseBody.length);

    // Content type analysis
    var contentType = oSession.oResponse.headers["Content-Type"];
    if (contentType.indexOf("application/json") >= 0) {
        try {
            var jsonData = JSON.parse(responseBody);
            FiddlerApplication.Log.LogString("JSON Response: " + JSON.stringify(jsonData, null, 2));
        } catch (e) {
            FiddlerApplication.Log.LogString("Invalid JSON response");
        }
    }
}

Traffic Modification

Request Modification

// Modify requests before sending
static function OnBeforeRequest(oSession: Session) {
    // Add custom headers
    if (oSession.HostnameIs("api.example.com")) {
        oSession.oRequest.headers.Add("X-Custom-Header", "FiddlerModified");
        oSession.oRequest.headers.Add("Authorization", "Bearer custom-token");
    }

    // Modify query parameters
    if (oSession.uriContains("/search")) {
        var url = oSession.fullUrl;
        if (url.indexOf("?") > 0) {
            url += "&debug=true&source=fiddler";
        } else {
            url += "?debug=true&source=fiddler";
        }
        oSession.fullUrl = url;
    }

    // Modify request body
    if (oSession.HTTPMethodIs("POST") && oSession.uriContains("/api/user")) {
        var requestBody = oSession.GetRequestBodyAsString();
        if (requestBody.length > 0) {
            try {
                var jsonData = JSON.parse(requestBody);
                jsonData.modified_by = "fiddler";
                jsonData.timestamp = new Date().toISOString();
                oSession.utilSetRequestBody(JSON.stringify(jsonData));
            } catch (e) {
                FiddlerApplication.Log.LogString("Failed to modify request body: " + e.message);
            }
        }
    }

    // Redirect requests
    if (oSession.HostnameIs("old-api.example.com")) {
        var newUrl = oSession.fullUrl.replace("old-api.example.com", "new-api.example.com");
        oSession.fullUrl = newUrl;
    }

    // Block requests
    if (oSession.uriContains("tracking") || oSession.uriContains("analytics")) {
        oSession.oResponse.headers.HTTPResponseCode = 204;
        oSession.oResponse.headers.HTTPResponseStatus = "204 No Content";
        oSession.utilCreateResponseAndBypassServer();
    }
}

Response Modification

// Modify responses before returning to client
static function OnBeforeResponse(oSession: Session) {
    // Add CORS headers
    if (oSession.HostnameIs("api.example.com")) {
        oSession.oResponse.headers.Add("Access-Control-Allow-Origin", "*");
        oSession.oResponse.headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        oSession.oResponse.headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization");
    }

    // Modify response status
    if (oSession.responseCode == 404 && oSession.uriContains("/api/fallback")) {
        oSession.oResponse.headers.HTTPResponseCode = 200;
        oSession.oResponse.headers.HTTPResponseStatus = "200 OK";
        oSession.utilSetResponseBody('{"status": "fallback", "data": []}');
    }

    // Inject content into HTML responses
    if (oSession.oResponse.headers.ExistsAndContains("Content-Type", "text/html")) {
        oSession.utilDecodeResponse();
        var responseBody = oSession.GetResponseBodyAsString();

        // Inject custom CSS
        var customCSS = '<style>body { border: 5px solid red !important; }</style>';
        responseBody = responseBody.replace("</head>", customCSS + "</head>");

        // Inject custom JavaScript
        var customJS = '<script>console.log("Fiddler injection successful");</script>';
        responseBody = responseBody.replace("</body>", customJS + "</body>");

        oSession.utilSetResponseBody(responseBody);
    }

    // Modify JSON responses
    if (oSession.oResponse.headers.ExistsAndContains("Content-Type", "application/json")) {
        oSession.utilDecodeResponse();
        var responseBody = oSession.GetResponseBodyAsString();

        try {
            var jsonData = JSON.parse(responseBody);

            // Add debug information
            jsonData._debug = {
                modified_by: "fiddler",
                original_status: oSession.responseCode,
                timestamp: new Date().toISOString()
            };

            // Modify specific fields
            if (jsonData.hasOwnProperty("price")) {
                jsonData.original_price = jsonData.price;
                jsonData.price = jsonData.price * 0.9; // 10% discount
            }

            oSession.utilSetResponseBody(JSON.stringify(jsonData, null, 2));

        } catch (e) {
            FiddlerApplication.Log.LogString("Failed to modify JSON response: " + e.message);
        }
    }

    // Cache control modification
    if (oSession.uriContains("/static/")) {
        oSession.oResponse.headers.Remove("Cache-Control");
        oSession.oResponse.headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
    }
}

API Testing and Debugging

REST API Testing

// Automated API testing with Fiddler
class APITester {
    static function TestAPIEndpoint(baseUrl, endpoint, method, headers, body) {
        var testSession = FiddlerApplication.oProxy.SendRequest(
            method + " " + baseUrl + endpoint + " HTTP/1.1\r\n" +
            "Host: " + GetHostFromUrl(baseUrl) + "\r\n" +
            headers + "\r\n" +
            body,
            null
        );

        return {
            statusCode: testSession.responseCode,
            responseBody: testSession.GetResponseBodyAsString(),
            responseTime: testSession.Timers.ClientDoneResponse - testSession.Timers.ClientBeginRequest
        };
    }

    static function RunAPITests() {
        var baseUrl = "https://api.example.com";
        var authToken = "Bearer your-auth-token";

        // Test 1: GET request
        var getResult = TestAPIEndpoint(
            baseUrl,
            "/users/123",
            "GET",
            "Authorization: " + authToken + "\r\nContent-Type: application/json",
            ""
        );

        FiddlerApplication.Log.LogString("GET Test - Status: " + getResult.statusCode + 
                                       ", Time: " + getResult.responseTime + "ms");

        // Test 2: POST request
        var postData = JSON.stringify({
            name: "Test User",
            email: "test@example.com"
        });

        var postResult = TestAPIEndpoint(
            baseUrl,
            "/users",
            "POST",
            "Authorization: " + authToken + "\r\nContent-Type: application/json",
            postData
        );

        FiddlerApplication.Log.LogString("POST Test - Status: " + postResult.statusCode + 
                                       ", Time: " + postResult.responseTime + "ms");

        // Test 3: Error handling
        var errorResult = TestAPIEndpoint(
            baseUrl,
            "/nonexistent",
            "GET",
            "Authorization: " + authToken,
            ""
        );

        FiddlerApplication.Log.LogString("Error Test - Status: " + errorResult.statusCode);
    }
}

// Performance testing
static function OnBeforeResponse(oSession: Session) {
    if (oSession.HostnameIs("api.example.com")) {
        var responseTime = oSession.Timers.ClientDoneResponse - oSession.Timers.ClientBeginRequest;
        var requestSize = oSession.requestBodyBytes.Length;
        var responseSize = oSession.responseBodyBytes.Length;

        // Log performance metrics
        FiddlerApplication.Log.LogString(
            "API Performance - " +
            "URL: " + oSession.fullUrl + ", " +
            "Method: " + oSession.RequestMethod + ", " +
            "Status: " + oSession.responseCode + ", " +
            "Time: " + responseTime + "ms, " +
            "Request Size: " + requestSize + " bytes, " +
            "Response Size: " + responseSize + " bytes"
        );

        // Alert on slow responses
        if (responseTime > 2000) {
            oSession["ui-color"] = "red";
            oSession["ui-bold"] = "true";
            FiddlerApplication.Log.LogString("SLOW RESPONSE ALERT: " + oSession.fullUrl + " took " + responseTime + "ms");
        }

        // Alert on large responses
        if (responseSize > 1048576) { // 1MB
            oSession["ui-color"] = "orange";
            FiddlerApplication.Log.LogString("LARGE RESPONSE ALERT: " + oSession.fullUrl + " returned " + responseSize + " bytes");
        }
    }
}

Authentication Testing

// Authentication and session testing
class AuthTester {
    static function TestAuthenticationFlow() {
        var baseUrl = "https://auth.example.com";

        // Step 1: Login request
        var loginData = JSON.stringify({
            username: "testuser",
            password: "testpass"
        });

        var loginResult = APITester.TestAPIEndpoint(
            baseUrl,
            "/login",
            "POST",
            "Content-Type: application/json",
            loginData
        );

        if (loginResult.statusCode == 200) {
            var loginResponse = JSON.parse(loginResult.responseBody);
            var authToken = loginResponse.token;

            FiddlerApplication.Log.LogString("Login successful, token: " + authToken);

            // Step 2: Test authenticated request
            var userResult = APITester.TestAPIEndpoint(
                baseUrl,
                "/user/profile",
                "GET",
                "Authorization: Bearer " + authToken,
                ""
            );

            FiddlerApplication.Log.LogString("Profile request - Status: " + userResult.statusCode);

            // Step 3: Test token expiration
            setTimeout(function() {
                var expiredResult = APITester.TestAPIEndpoint(
                    baseUrl,
                    "/user/profile",
                    "GET",
                    "Authorization: Bearer " + authToken,
                    ""
                );

                if (expiredResult.statusCode == 401) {
                    FiddlerApplication.Log.LogString("Token correctly expired");
                } else {
                    FiddlerApplication.Log.LogString("WARNING: Token should have expired");
                }
            }, 3600000); // 1 hour

        } else {
            FiddlerApplication.Log.LogString("Login failed - Status: " + loginResult.statusCode);
        }
    }

    static function TestSessionSecurity() {
        // Monitor for insecure authentication patterns
        static function OnBeforeRequest(oSession: Session) {
            // Check for credentials in URL
            if (oSession.fullUrl.toLowerCase().indexOf("password=") >= 0 ||
                oSession.fullUrl.toLowerCase().indexOf("token=") >= 0) {
                oSession["ui-color"] = "red";
                oSession["ui-bold"] = "true";
                FiddlerApplication.Log.LogString("SECURITY ALERT: Credentials in URL - " + oSession.fullUrl);
            }

            // Check for HTTP authentication on non-HTTPS
            if (!oSession.isHTTPS && oSession.oRequest.headers.Exists("Authorization")) {
                oSession["ui-color"] = "red";
                oSession["ui-bold"] = "true";
                FiddlerApplication.Log.LogString("SECURITY ALERT: Authentication over HTTP - " + oSession.fullUrl);
            }
        }

        static function OnBeforeResponse(oSession: Session) {
            // Check for secure cookie settings
            if (oSession.oResponse.headers.Exists("Set-Cookie")) {
                var cookies = oSession.oResponse.headers["Set-Cookie"];
                if (cookies.indexOf("Secure") < 0 || cookies.indexOf("HttpOnly") < 0) {
                    oSession["ui-color"] = "orange";
                    FiddlerApplication.Log.LogString("SECURITY WARNING: Insecure cookie settings - " + oSession.fullUrl);
                }
            }
        }
    }
}

Automation and Scripting

Python Integration

#!/usr/bin/env python3
# fiddler-automation.py

import requests
import json
import time
import subprocess
import os
from urllib.parse import urlparse

class FiddlerAutomation:
    def __init__(self, fiddler_host="127.0.0.1", fiddler_port=8888):
        self.proxy_url = f"http://{fiddler_host}:{fiddler_port}"
        self.proxies = {
            'http': self.proxy_url,
            'https': self.proxy_url
        }
        self.session = requests.Session()
        self.session.proxies.update(self.proxies)

        # Disable SSL verification when using Fiddler proxy
        self.session.verify = False
        requests.packages.urllib3.disable_warnings()

    def start_fiddler(self, fiddler_path=None):
        """Start Fiddler programmatically"""
        if fiddler_path is None:
            fiddler_path = r"C:\Program Files (x86)\Fiddler2\Fiddler.exe"

        if os.path.exists(fiddler_path):
            subprocess.Popen([fiddler_path])
            time.sleep(5)  # Wait for Fiddler to start
            print("✅ Fiddler started")
            return True
        else:
            print("❌ Fiddler not found at specified path")
            return False

    def test_proxy_connection(self):
        """Test if Fiddler proxy is working"""
        try:
            response = self.session.get("http://httpbin.org/ip", timeout=10)
            if response.status_code == 200:
                print("✅ Fiddler proxy connection successful")
                return True
        except Exception as e:
            print(f"❌ Fiddler proxy connection failed: {e}")
            return False

    def capture_api_traffic(self, base_url, endpoints, auth_token=None):
        """Capture traffic for multiple API endpoints"""
        results = []

        headers = {'Content-Type': 'application/json'}
        if auth_token:
            headers['Authorization'] = f'Bearer {auth_token}'

        for endpoint in endpoints:
            url = f"{base_url}{endpoint}"
            start_time = time.time()

            try:
                response = self.session.get(url, headers=headers)
                end_time = time.time()

                result = {
                    'url': url,
                    'method': 'GET',
                    'status_code': response.status_code,
                    'response_time': round((end_time - start_time) * 1000, 2),
                    'response_size': len(response.content),
                    'headers': dict(response.headers),
                    'captured_at': time.strftime('%Y-%m-%d %H:%M:%S')
                }

                if response.headers.get('content-type', '').startswith('application/json'):
                    try:
                        result['response_body'] = response.json()
                    except:
                        result['response_body'] = response.text

                results.append(result)
                print(f"📊 Captured: {url} - {response.status_code} ({result['response_time']}ms)")

            except Exception as e:
                print(f"❌ Error capturing {url}: {e}")
                results.append({
                    'url': url,
                    'method': 'GET',
                    'error': str(e),
                    'captured_at': time.strftime('%Y-%m-%d %H:%M:%S')
                })

        return results

    def load_test_with_fiddler(self, url, num_requests=10, delay=1):
        """Perform load testing while capturing traffic"""
        print(f"🚀 Starting load test: {num_requests} requests to {url}")

        results = []
        for i in range(num_requests):
            start_time = time.time()

            try:
                response = self.session.get(url)
                end_time = time.time()

                result = {
                    'request_number': i + 1,
                    'status_code': response.status_code,
                    'response_time': round((end_time - start_time) * 1000, 2),
                    'response_size': len(response.content),
                    'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
                }

                results.append(result)
                print(f"Request {i+1}: {response.status_code} ({result['response_time']}ms)")

            except Exception as e:
                print(f"Request {i+1} failed: {e}")
                results.append({
                    'request_number': i + 1,
                    'error': str(e),
                    'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
                })

            if delay > 0 and i < num_requests - 1:
                time.sleep(delay)

        # Calculate statistics
        successful_requests = [r for r in results if 'error' not in r and r['status_code'] == 200]
        if successful_requests:
            response_times = [r['response_time'] for r in successful_requests]
            stats = {
                'total_requests': num_requests,
                'successful_requests': len(successful_requests),
                'failed_requests': num_requests - len(successful_requests),
                'avg_response_time': round(sum(response_times) / len(response_times), 2),
                'min_response_time': min(response_times),
                'max_response_time': max(response_times)
            }

            print(f"\n📊 Load Test Results:")
            print(f"   Total Requests: {stats['total_requests']}")
            print(f"   Successful: {stats['successful_requests']}")
            print(f"   Failed: {stats['failed_requests']}")
            print(f"   Avg Response Time: {stats['avg_response_time']}ms")
            print(f"   Min Response Time: {stats['min_response_time']}ms")
            print(f"   Max Response Time: {stats['max_response_time']}ms")

            return results, stats

        return results, None

    def security_scan_with_fiddler(self, base_url, test_payloads):
        """Perform security testing while capturing traffic"""
        print(f"🔒 Starting security scan on {base_url}")

        vulnerabilities = []

        for payload_type, payloads in test_payloads.items():
            print(f"Testing {payload_type}...")

            for payload in payloads:
                test_url = f"{base_url}?test={payload}"

                try:
                    response = self.session.get(test_url)

                    # Check for potential vulnerabilities
                    if payload_type == "xss" and payload in response.text:
                        vulnerabilities.append({
                            'type': 'XSS',
                            'url': test_url,
                            'payload': payload,
                            'evidence': 'Payload reflected in response'
                        })

                    elif payload_type == "sql_injection" and any(error in response.text.lower() for error in 
                        ['sql syntax', 'mysql_fetch', 'ora-', 'postgresql']):
                        vulnerabilities.append({
                            'type': 'SQL Injection',
                            'url': test_url,
                            'payload': payload,
                            'evidence': 'Database error in response'
                        })

                    elif payload_type == "path_traversal" and "root:" in response.text:
                        vulnerabilities.append({
                            'type': 'Path Traversal',
                            'url': test_url,
                            'payload': payload,
                            'evidence': 'System file content in response'
                        })

                except Exception as e:
                    print(f"Error testing payload {payload}: {e}")

        if vulnerabilities:
            print(f"\n🚨 Found {len(vulnerabilities)} potential vulnerabilities:")
            for vuln in vulnerabilities:
                print(f"   {vuln['type']}: {vuln['url']}")
        else:
            print("✅ No obvious vulnerabilities detected")

        return vulnerabilities

    def export_captured_data(self, data, filename):
        """Export captured data to JSON file"""
        with open(filename, 'w') as f:
            json.dump(data, f, indent=2)
        print(f"💾 Data exported to {filename}")

def main():
    # Initialize Fiddler automation
    fiddler = FiddlerAutomation()

    # Test proxy connection
    if not fiddler.test_proxy_connection():
        print("Please ensure Fiddler is running and proxy is configured")
        return

    # Example 1: API traffic capture
    print("\n=== API Traffic Capture ===")
    api_endpoints = [
        "/api/users",
        "/api/products",
        "/api/orders",
        "/api/analytics"
    ]

    api_results = fiddler.capture_api_traffic(
        "https://jsonplaceholder.typicode.com",
        api_endpoints
    )

    fiddler.export_captured_data(api_results, "api_traffic_capture.json")

    # Example 2: Load testing
    print("\n=== Load Testing ===")
    load_results, load_stats = fiddler.load_test_with_fiddler(
        "https://httpbin.org/delay/1",
        num_requests=5,
        delay=0.5
    )

    if load_stats:
        fiddler.export_captured_data({
            'results': load_results,
            'statistics': load_stats
        }, "load_test_results.json")

    # Example 3: Security testing
    print("\n=== Security Testing ===")
    test_payloads = {
        "xss": [
            "<script>alert('XSS')</script>",
            "javascript:alert('XSS')",
            "<img src=x onerror=alert('XSS')>"
        ],
        "sql_injection": [
            "' OR '1'='1",
            "'; DROP TABLE users; --",
            "' UNION SELECT * FROM users --"
        ],
        "path_traversal": [
            "../../../etc/passwd",
            "..\\..\\..\\windows\\system32\\drivers\\etc\\hosts",
            "....//....//....//etc/passwd"
        ]
    }

    security_results = fiddler.security_scan_with_fiddler(
        "https://httpbin.org/get",
        test_payloads
    )

    fiddler.export_captured_data(security_results, "security_scan_results.json")

    print("\n🎉 Fiddler automation completed!")

if __name__ == "__main__":
    main()

Performance Analysis

Response Time Monitoring

// Performance monitoring script
class PerformanceMonitor {
    static var performanceData = [];

    static function OnBeforeResponse(oSession: Session) {
        var responseTime = oSession.Timers.ClientDoneResponse - oSession.Timers.ClientBeginRequest;
        var dnsTime = oSession.Timers.DNSTime;
        var connectTime = oSession.Timers.TCPConnectTime;
        var sslTime = oSession.Timers.HTTPSHandshakeTime;
        var serverTime = oSession.Timers.ServerGotRequest - oSession.Timers.ServerBeginResponse;

        var perfData = {
            url: oSession.fullUrl,
            method: oSession.RequestMethod,
            statusCode: oSession.responseCode,
            totalTime: responseTime,
            dnsTime: dnsTime,
            connectTime: connectTime,
            sslTime: sslTime,
            serverTime: serverTime,
            requestSize: oSession.requestBodyBytes.Length,
            responseSize: oSession.responseBodyBytes.Length,
            timestamp: new Date().toISOString()
        };

        performanceData.push(perfData);

        // Real-time performance alerts
        if (responseTime > 5000) {
            oSession["ui-color"] = "red";
            oSession["ui-bold"] = "true";
            FiddlerApplication.Log.LogString("PERFORMANCE ALERT: Slow response (" + responseTime + "ms) - " + oSession.fullUrl);
        }

        if (oSession.responseBodyBytes.Length > 5242880) { // 5MB
            oSession["ui-color"] = "orange";
            FiddlerApplication.Log.LogString("SIZE ALERT: Large response (" + oSession.responseBodyBytes.Length + " bytes) - " + oSession.fullUrl);
        }

        // Log detailed timing for API calls
        if (oSession.HostnameIs("api.example.com")) {
            FiddlerApplication.Log.LogString(
                "API Timing - " + oSession.fullUrl + 
                " | Total: " + responseTime + "ms" +
                " | DNS: " + dnsTime + "ms" +
                " | Connect: " + connectTime + "ms" +
                " | SSL: " + sslTime + "ms" +
                " | Server: " + serverTime + "ms"
            );
        }
    }

    static function GeneratePerformanceReport() {
        var report = "Performance Analysis Report\n";
        report += "Generated: " + new Date().toISOString() + "\n\n";

        if (performanceData.length == 0) {
            report += "No performance data collected.\n";
            return report;
        }

        // Calculate statistics
        var totalRequests = performanceData.length;
        var totalTime = 0;
        var slowRequests = 0;
        var largeResponses = 0;

        for (var i = 0; i < performanceData.length; i++) {
            var data = performanceData[i];
            totalTime += data.totalTime;

            if (data.totalTime > 2000) slowRequests++;
            if (data.responseSize > 1048576) largeResponses++;
        }

        var avgResponseTime = totalTime / totalRequests;

        report += "Summary Statistics:\n";
        report += "- Total Requests: " + totalRequests + "\n";
        report += "- Average Response Time: " + avgResponseTime.toFixed(2) + "ms\n";
        report += "- Slow Requests (>2s): " + slowRequests + " (" + ((slowRequests/totalRequests)*100).toFixed(1) + "%)\n";
        report += "- Large Responses (>1MB): " + largeResponses + " (" + ((largeResponses/totalRequests)*100).toFixed(1) + "%)\n\n";

        // Top 10 slowest requests
        performanceData.sort(function(a, b) { return b.totalTime - a.totalTime; });

        report += "Top 10 Slowest Requests:\n";
        for (var j = 0; j < Math.min(10, performanceData.length); j++) {
            var slow = performanceData[j];
            report += (j+1) + ". " + slow.url + " - " + slow.totalTime + "ms\n";
        }

        FiddlerApplication.Log.LogString(report);
        return report;
    }
}

Security Testing

SSL/TLS Analysis

// SSL/TLS security analysis
static function OnBeforeResponse(oSession: Session) {
    if (oSession.isHTTPS) {
        // Check SSL/TLS version
        var sslVersion = oSession["https-Client-Certificate"];
        if (sslVersion && sslVersion.indexOf("TLS 1.0") >= 0) {
            oSession["ui-color"] = "red";
            FiddlerApplication.Log.LogString("SECURITY WARNING: Weak TLS version detected - " + oSession.fullUrl);
        }

        // Check for weak ciphers
        var cipher = oSession["https-Client-Cipher"];
        if (cipher && (cipher.indexOf("RC4") >= 0 || cipher.indexOf("DES") >= 0)) {
            oSession["ui-color"] = "red";
            FiddlerApplication.Log.LogString("SECURITY WARNING: Weak cipher detected - " + oSession.fullUrl);
        }

        // Check certificate validity
        var certError = oSession["https-Client-Cert-Error"];
        if (certError && certError.length > 0) {
            oSession["ui-color"] = "orange";
            FiddlerApplication.Log.LogString("CERTIFICATE WARNING: " + certError + " - " + oSession.fullUrl);
        }
    } else {
        // Check for sensitive data over HTTP
        var requestBody = oSession.GetRequestBodyAsString();
        var responseBody = oSession.GetResponseBodyAsString();

        var sensitivePatterns = [
            "password", "passwd", "pwd",
            "token", "auth", "session",
            "credit", "card", "ssn",
            "social", "security"
        ];

        for (var i = 0; i < sensitivePatterns.length; i++) {
            var pattern = sensitivePatterns[i];
            if (requestBody.toLowerCase().indexOf(pattern) >= 0 || 
                responseBody.toLowerCase().indexOf(pattern) >= 0) {
                oSession["ui-color"] = "red";
                oSession["ui-bold"] = "true";
                FiddlerApplication.Log.LogString("SECURITY ALERT: Sensitive data over HTTP - " + oSession.fullUrl);
                break;
            }
        }
    }

    // Check security headers
    var securityHeaders = [
        "Strict-Transport-Security",
        "Content-Security-Policy",
        "X-Frame-Options",
        "X-Content-Type-Options",
        "X-XSS-Protection"
    ];

    var missingHeaders = [];
    for (var j = 0; j < securityHeaders.length; j++) {
        if (!oSession.oResponse.headers.Exists(securityHeaders[j])) {
            missingHeaders.push(securityHeaders[j]);
        }
    }

    if (missingHeaders.length > 0) {
        oSession["ui-color"] = "yellow";
        FiddlerApplication.Log.LogString("SECURITY INFO: Missing headers - " + missingHeaders.join(", ") + " - " + oSession.fullUrl);
    }
}

Troubleshooting

Common Issues

# Fiddler not capturing traffic
# 1. Check proxy settings
netsh winhttp show proxy

# 2. Reset proxy settings
netsh winhttp reset proxy

# 3. Restart Fiddler as administrator
# Right-click Fiddler → Run as administrator

# 4. Check Windows Firewall
netsh advfirewall firewall show rule name="Fiddler"

# HTTPS decryption not working
# 1. Reinstall Fiddler certificate
# Tools → Options → HTTPS → Actions → Reset All Certificates

# 2. Clear browser certificates
# Chrome: Settings → Privacy → Clear browsing data → Certificates
# Firefox: Options → Privacy → Certificates → View Certificates

# 3. Check certificate store
certlm.msc
# Verify FiddlerRoot certificate in Trusted Root Certification Authorities

# Mobile device not connecting
# 1. Verify network connectivity
ping [Fiddler-PC-IP]

# 2. Check firewall rules
netsh advfirewall firewall add rule name="Fiddler" dir=in action=allow protocol=TCP localport=8888

# 3. Verify proxy configuration on device
# Settings → Wi-Fi → Network → Proxy → Manual
# Server: [Fiddler-PC-IP]
# Port: 8888

# Performance issues
# 1. Disable unnecessary features
# Rules → Automatic Breakpoints → Disabled
# Rules → Performance → Stream responses

# 2. Increase memory allocation
# Edit Fiddler.exe.config
# <runtime>
#   <gcServer enabled="true"/>
#   <gcConcurrent enabled="true"/>
# </runtime>

# 3. Clear session list regularly
# Edit → Remove → All Sessions

Advanced Debugging

// Advanced debugging and diagnostics
class FiddlerDiagnostics {
    static function DiagnoseConnection(oSession) {
        var diagnostics = "Connection Diagnostics for: " + oSession.fullUrl + "\n";

        // Timing analysis
        diagnostics += "Timing Breakdown:\n";
        diagnostics += "- DNS Lookup: " + oSession.Timers.DNSTime + "ms\n";
        diagnostics += "- TCP Connect: " + oSession.Timers.TCPConnectTime + "ms\n";
        diagnostics += "- SSL Handshake: " + oSession.Timers.HTTPSHandshakeTime + "ms\n";
        diagnostics += "- Request Sent: " + (oSession.Timers.ServerGotRequest - oSession.Timers.ClientBeginRequest) + "ms\n";
        diagnostics += "- Server Processing: " + (oSession.Timers.ServerBeginResponse - oSession.Timers.ServerGotRequest) + "ms\n";
        diagnostics += "- Response Received: " + (oSession.Timers.ClientDoneResponse - oSession.Timers.ServerBeginResponse) + "ms\n";

        // Connection details
        diagnostics += "\nConnection Details:\n";
        diagnostics += "- Client IP: " + oSession.clientIP + "\n";
        diagnostics += "- Server IP: " + oSession.m_hostIP + "\n";
        diagnostics += "- Port: " + oSession.port + "\n";
        diagnostics += "- Protocol: " + (oSession.isHTTPS ? "HTTPS" : "HTTP") + "\n";

        // Error analysis
        if (oSession.responseCode >= 400) {
            diagnostics += "\nError Analysis:\n";
            diagnostics += "- Status Code: " + oSession.responseCode + "\n";
            diagnostics += "- Status Text: " + oSession.oResponse.headers.HTTPResponseStatus + "\n";

            if (oSession.responseCode >= 500) {
                diagnostics += "- Type: Server Error\n";
                diagnostics += "- Recommendation: Check server logs and configuration\n";
            } else if (oSession.responseCode >= 400) {
                diagnostics += "- Type: Client Error\n";
                diagnostics += "- Recommendation: Check request format and authentication\n";
            }
        }

        FiddlerApplication.Log.LogString(diagnostics);
        return diagnostics;
    }

    static function AnalyzePerformanceBottlenecks(oSession) {
        var totalTime = oSession.Timers.ClientDoneResponse - oSession.Timers.ClientBeginRequest;
        var analysis = "Performance Analysis for: " + oSession.fullUrl + "\n";

        // Identify bottlenecks
        var dnsTime = oSession.Timers.DNSTime;
        var connectTime = oSession.Timers.TCPConnectTime;
        var sslTime = oSession.Timers.HTTPSHandshakeTime;
        var serverTime = oSession.Timers.ServerBeginResponse - oSession.Timers.ServerGotRequest;
        var transferTime = oSession.Timers.ClientDoneResponse - oSession.Timers.ServerBeginResponse;

        analysis += "Bottleneck Analysis:\n";

        if (dnsTime > totalTime * 0.3) {
            analysis += "- DNS BOTTLENECK: " + dnsTime + "ms (" + ((dnsTime/totalTime)*100).toFixed(1) + "%)\n";
            analysis += "  Recommendation: Use DNS caching or faster DNS servers\n";
        }

        if (connectTime > totalTime * 0.3) {
            analysis += "- CONNECTION BOTTLENECK: " + connectTime + "ms (" + ((connectTime/totalTime)*100).toFixed(1) + "%)\n";
            analysis += "  Recommendation: Use connection pooling or CDN\n";
        }

        if (sslTime > totalTime * 0.3) {
            analysis += "- SSL BOTTLENECK: " + sslTime + "ms (" + ((sslTime/totalTime)*100).toFixed(1) + "%)\n";
            analysis += "  Recommendation: Optimize SSL configuration or use session resumption\n";
        }

        if (serverTime > totalTime * 0.5) {
            analysis += "- SERVER BOTTLENECK: " + serverTime + "ms (" + ((serverTime/totalTime)*100).toFixed(1) + "%)\n";
            analysis += "  Recommendation: Optimize server-side processing\n";
        }

        if (transferTime > totalTime * 0.3) {
            analysis += "- TRANSFER BOTTLENECK: " + transferTime + "ms (" + ((transferTime/totalTime)*100).toFixed(1) + "%)\n";
            analysis += "  Recommendation: Compress responses or use CDN\n";
        }

        FiddlerApplication.Log.LogString(analysis);
        return analysis;
    }
}

This comprehensive Fiddler cheatsheet provides everything needed for professional web debugging, API testing, and security analysis, from basic traffic capture to advanced automation and performance monitoring scenarios.