Fiddler Cheatsheet
- :material-content-copy: ** Copy to Clipboard**
- :material-file-pdf-box: ** Descargar PDF**
■/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.