Saltar a contenido

Fiddler Cheatsheet

■/div titulada

Sinopsis

Fiddler es una poderosa herramienta proxy depuradora web que captura el tráfico HTTP y HTTPS entre su computadora y el Internet. Permite a los desarrolladores, probadores y profesionales de seguridad inspeccionar, modificar y depurar el tráfico web en tiempo real, lo que lo convierte en una herramienta esencial para el desarrollo web, pruebas de API y análisis de seguridad.

Características clave

  • Traffic Capture: Supervise todo el tráfico HTTP/HTTPS desde cualquier aplicación
  • Inspección de solicitudes y respuestas: Análisis detallado de cabeceras, cuerpos y tiempo
  • ** Modificación comercial**: Editar solicitudes y respuestas sobre el terreno
  • ** Análisis de rendimiento**: Identificar los cuellos de botella y las oportunidades de optimización
  • ** Pruebas de seguridad**: Analizar autenticación, gestión de sesiones y vulnerabilidades
  • API Testing: Prueba y depura API y servicios web de REST
  • Mobile Testing: Capture traffic from mobile devices and applications
  • Scripting Support: Automatizar tareas con JScript. scripts NET y C#

Instalación

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 en todas partes (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 Instalación

# 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

Configuración básica

Configuración inicial

# 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

Configuración de dispositivos móviles

# 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

Captura de tráfico y análisis

Supervisión básica del tráfico

// 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);
        }
    }
}

Filtro avanzado

// 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);
}

Solicitud/Inspección de respuesta

// 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");
        }
    }
}

Modificación del tráfico

Solicitud de modificación

// 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();
    }
}

Modificación de la respuesta

// 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

Pruebas REST API

// 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");
        }
    }
}

Pruebas de autenticación

// 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);
                }
            }
        }
    }
}

Automatización y 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()

Análisis de la ejecución

Seguimiento del tiempo de respuesta

// 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;
    }
}

Pruebas de seguridad

Análisis SSL/TLS

// 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);
    }
}

Solución de problemas

Cuestiones comunes

# 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

Depuración avanzada

// 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;
    }
}

Esta hoja de trampa integral de Fiddler proporciona todo lo necesario para depurar web profesional, pruebas de API y análisis de seguridad, desde captura de tráfico básico a escenarios avanzados de automatización y monitoreo de rendimiento.