C

Comprehensive Api Fuzzing Bug

Production-ready skill that handles skill, should, used, user. Includes structured workflows, validation checks, and reusable patterns for security.

SkillClipticssecurityv1.0.0MIT
0 views0 copies

Comprehensive API Fuzzing Bug

Test REST, GraphQL, and SOAP APIs for security vulnerabilities through fuzzing during authorized bug bounty and penetration testing engagements. This skill covers endpoint discovery, parameter fuzzing, authentication bypass testing, injection testing, rate limit validation, and automated vulnerability scanning.

When to Use This Skill

Choose Comprehensive API Fuzzing Bug when you need to:

  • Fuzz API endpoints for injection vulnerabilities (SQLi, NoSQLi, SSRF, command injection)
  • Test authentication and authorization boundaries in REST and GraphQL APIs
  • Discover undocumented API endpoints and parameters
  • Automate API security testing in bug bounty programs

Consider alternatives when:

  • You need to test web application UI vulnerabilities (use Burp Suite / OWASP ZAP)
  • You need static code analysis of API source code (use Semgrep or SonarQube)
  • You need to design secure APIs from scratch (use API Security Best Practices skill)

Quick Start

pip install requests urllib3
import requests import json from urllib.parse import urljoin class APIFuzzer: """Basic API fuzzer for authorized security testing.""" def __init__(self, base_url, auth_headers=None): self.base_url = base_url.rstrip('/') self.session = requests.Session() if auth_headers: self.session.headers.update(auth_headers) self.findings = [] def fuzz_parameter(self, endpoint, method, param_name, payloads): """Fuzz a single parameter with a list of payloads.""" url = f"{self.base_url}{endpoint}" results = [] for payload in payloads: try: if method.upper() == "GET": resp = self.session.get(url, params={param_name: payload}, timeout=10) else: resp = self.session.post(url, json={param_name: payload}, timeout=10) result = { 'payload': payload, 'status': resp.status_code, 'length': len(resp.content), 'time': resp.elapsed.total_seconds(), } # Flag anomalous responses if resp.status_code == 500: result['flag'] = 'SERVER_ERROR' self.findings.append({ 'endpoint': endpoint, 'param': param_name, 'payload': payload, 'issue': 'Internal server error — possible injection' }) elif resp.elapsed.total_seconds() > 5: result['flag'] = 'SLOW_RESPONSE' results.append(result) except requests.exceptions.Timeout: results.append({'payload': payload, 'flag': 'TIMEOUT'}) return results # Common fuzzing payloads SQL_PAYLOADS = [ "' OR '1'='1", "1; DROP TABLE users--", "admin'--", "' UNION SELECT NULL--", "1' AND SLEEP(5)--", ] NOSQL_PAYLOADS = [ '{"$gt":""}', '{"$ne":""}', '{"$regex":".*"}', '{"$where":"sleep(5000)"}', ] SSRF_PAYLOADS = [ "http://127.0.0.1:80", "http://169.254.169.254/latest/meta-data/", "http://[::1]", "http://0x7f000001", ] # Example usage (authorized testing only) # fuzzer = APIFuzzer("https://target-api.example.com", {"Authorization": "Bearer TOKEN"}) # results = fuzzer.fuzz_parameter("/api/users", "GET", "id", SQL_PAYLOADS) # for r in results: # if 'flag' in r: # print(f"[{r['flag']}] Payload: {r['payload']}")

Core Concepts

Fuzzing Categories

CategoryTargetPayloads
SQL InjectionDatabase queries' OR 1=1--, UNION SELECT, time-based
NoSQL InjectionMongoDB/CouchDB queries{"$gt":""}, {"$ne":""}
SSRFURL parameters, webhookshttp://169.254.169.254, http://localhost
Command InjectionSystem calls; ls, `
Path TraversalFile paths../../etc/passwd, ..%2f..%2f
XSS (reflected)HTML-rendered responses<script>alert(1)</script>
IDORObject identifiersSequential IDs, UUID guessing
Mass AssignmentObject creation/updateExtra fields in JSON body

GraphQL Introspection and Fuzzing

import requests import json def graphql_introspect(url, headers=None): """Attempt GraphQL schema introspection.""" introspection_query = """ query IntrospectionQuery { __schema { types { name kind fields { name type { name kind } args { name type { name } } } } mutationType { name } queryType { name } } } """ resp = requests.post(url, json={"query": introspection_query}, headers=headers, timeout=15) if resp.status_code == 200: data = resp.json() if 'errors' not in data: types = data['data']['__schema']['types'] user_types = [t for t in types if not t['name'].startswith('__')] print(f"Schema exposed: {len(user_types)} types") for t in user_types[:10]: fields = [f['name'] for f in (t.get('fields') or [])] print(f" {t['name']}: {fields[:5]}") return data print("Introspection disabled or blocked") return None def fuzz_graphql_query(url, query_name, field_name, payloads, headers=None): """Fuzz a GraphQL query parameter.""" findings = [] for payload in payloads: query = f'query {{ {query_name}({field_name}: "{payload}") {{ id }} }}' try: resp = requests.post(url, json={"query": query}, headers=headers, timeout=10) if resp.status_code == 500 or 'error' in resp.text.lower(): findings.append({ 'payload': payload, 'status': resp.status_code, 'response_snippet': resp.text[:200] }) except Exception as e: findings.append({'payload': payload, 'error': str(e)}) return findings # graphql_introspect("https://target.com/graphql")

Configuration

ParameterDescriptionDefault
base_urlTarget API base URLRequired
auth_tokenAuthorization tokenRequired
timeoutRequest timeout (seconds)10
rate_limitMax requests per second10
payload_setFuzzing payload categories["sqli", "xss"]
follow_redirectsFollow HTTP redirectsfalse
proxyProxy for traffic inspection (Burp)None
encodingPayload encoding (url, base64, double)"none"

Best Practices

  1. Always operate within authorized scope — Only test APIs you have written authorization to test (bug bounty scope, pentest contract, or your own applications). Unauthorized API testing is illegal. Document your authorization and stay within defined boundaries.

  2. Start with passive reconnaissance before active fuzzing — Enumerate endpoints from API documentation, JavaScript files, mobile app traffic, and OpenAPI/Swagger specs before fuzzing. This identifies the attack surface and prevents wasting time on non-existent endpoints.

  3. Proxy all traffic through Burp Suite for inspection — Set proxies={"http": "http://127.0.0.1:8080"} to route requests through Burp. This captures every request/response for later analysis, replay, and evidence collection for bug bounty reports.

  4. Use time-based payloads to confirm blind injection — If error-based detection fails, use time-based payloads (e.g., SLEEP(5) for SQL, setTimeout for JS). A consistent 5-second delay confirms the injection point even when the response content doesn't change.

  5. Test authorization boundaries, not just authentication — Many APIs authenticate users but fail to authorize actions. Test IDOR (accessing other users' data by changing IDs), vertical privilege escalation (accessing admin functions with user tokens), and horizontal access control violations.

Common Issues

Fuzzer produces too many false positives — 500 errors may indicate WAF blocks, not vulnerabilities. Baseline the application's normal error responses first, then compare fuzzing results against the baseline. A true injection changes response content, timing, or behavior predictably.

Rate limiting blocks fuzzing before completion — Respect rate limits to avoid IP bans. Add delays between requests (time.sleep(0.1)), use multiple source IPs if authorized, and prioritize high-value payloads. For bug bounties, check the program's rate limit policy.

GraphQL introspection is disabled — Many production APIs disable introspection. Try alternate endpoints (/graphql, /api/graphql, /gql), check for development/staging environments, or use tools like clairvoyance that infer schema through wordlist-based field guessing.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates