Aller au contenu

Feuilles chauffantes pour enfants

- :material-content-copy: **[Copier sur le presse-papiers] (__LINK_0__)** - **[Télécharger PDF](__LINK_0__)**

Aperçu général

Fiddler est un puissant outil de débogage web qui capture le trafic HTTP et HTTPS entre votre ordinateur et Internet. Il permet aux développeurs, aux testeurs et aux professionnels de la sécurité d'inspecter, de modifier et de déboguer le trafic web en temps réel, ce qui en fait un outil essentiel pour le développement web, les tests API et l'analyse de sécurité.

Caractéristiques principales

  • Capture de trafic: Surveiller tout le trafic HTTP/HTTPS de toute application
  • Demander ou répondre à une inspection : Analyse détaillée des en-têtes, des organes et du calendrier
  • ** Modification de la circulation**: Modifier les demandes et les réponses à la volée
  • ** Analyse du rendement**: Identifier les goulets d'étranglement et les possibilités d'optimisation
  • ** Tests de sécurité** : Analyser l'authentification, la gestion des sessions et les vulnérabilités
  • API Testing: Test et débogage API REST et services web
  • ** Essais mobiles**: Capturer le trafic des appareils et applications mobiles
  • ** Support de script**: Automatiser les tâches avec JScript. scripts NET et C#

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 partout (plateforme de choc)

# 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
```_

### Installation Docker

```bash
# 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
```_

## Configuration de base

### Configuration initiale

```bash
# 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

Configuration du décryptage HTTPS

# 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

Configuration du périphérique mobile

# 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

Capture et analyse du trafic

Surveillance de base de la circulation

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

Filtre avancé

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

Demande d'inspection/réponse

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

Modification de la circulation

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

Réponse

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

Essai et débogage de l'API

Essai de l'API REST

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

Essais d'authentification

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

Automatisation et écriture

Intégration de Python

#!/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()

Analyse des résultats

Surveillance du temps de réponse

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

Essais de sécurité

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

Dépannage

Questions communes

# 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

Déboguage avancé

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

Cette feuille de tricherie Fiddler complète fournit tout ce qui est nécessaire pour le débogage web professionnel, les tests d'API et l'analyse de sécurité, de la capture de trafic de base à des scénarios avancés d'automatisation et de surveillance des performances.