Skip to content

Latest commit

 

History

History
2363 lines (1745 loc) · 99.4 KB

File metadata and controls

2363 lines (1745 loc) · 99.4 KB

📖 APILeak CLI Reference

Complete command-line interface reference for APILeak v0.2.0 - Enterprise API security testing tool.

Table of Contents

Global Options

These options are available for all commands:

Option Description Default
--no-banner Suppress banner output false
--help Show help message and exit -

Commands Overview

APILeak provides the following main commands:

Command Purpose Use Case
dir Directory/endpoint fuzzing Discover hidden endpoints and directories
par Parameter fuzzing Find hidden parameters in API endpoints
scan Orchestrated OWASP scan (primary) Runs discovery + all registered OWASP modules and drives the CI gate
owasp OWASP module group List modules, or run exactly one OWASP module in isolation (owasp <key>)
jwt JWT security utilities JWT token manipulation and security testing

Deprecation. full and main are deprecated, hidden aliases of scan. They still work and forward to scan (printing a one-line deprecation notice to stderr), but you should migrate scripts to scan. Module selection through the alias also migrates: full --modules bolaapileaks owasp bola.

Help System

APILeak provides comprehensive help at multiple levels:

# Main help - shows all commands and global options
python apileaks.py --help

# Command-specific help - shows all options for a specific command
python apileaks.py scan --help
python apileaks.py owasp --help
python apileaks.py dir --help
python apileaks.py par --help

# JWT utilities help
python apileaks.py jwt --help
python apileaks.py jwt decode --help
python apileaks.py jwt encode --help

Directory Fuzzing (dir)

Discover hidden API endpoints and administrative interfaces.

Purpose. The dir command performs directory and endpoint fuzzing against a target: it sends candidate paths (from wordlists and/or imported API specs), classifies each discovered endpoint, and optionally recurses into promising paths. On top of raw discovery it layers an opt-in triage workflow (status grouping, session persistence, exports, an interactive table) and can feed discovered endpoints straight into an OWASP scan.

Option groups at a glance:

Group What it controls
Discovery Control Recursion depth, request budget, and concurrency
Proxy Routing traffic through an intercepting proxy
Discovery Robustness Seeds/extensions, request context, response matchers/filters, method/GraphQL probing, resilience, TLS, secret detection, machine output, storage-time scope, recursion scope, hit confirmation, checkpoint/resume
Discovery Triage Sessions, exports, and the interactive table
Discovery-to-Scan Integration Batch-scanning discovered endpoints
Status Code Filtering How --status-code is parsed in triage mode
Rate Limiting and User-Agent Pacing and identifying discovery requests

Syntax

python apileaks.py dir [OPTIONS]

Required Options

Option Description Example
--target, -t Target URL to scan --target https://api.example.com

Optional Parameters

Option Description Default Example
--wordlist, -w Wordlist file for directory fuzzing wordlists/endpoints.txt --wordlist custom_endpoints.txt
--output, -o Output filename for reports Auto-generated --output my-scan
--log-level Logging level WARNING --log-level DEBUG
--log-file Log file path Console only --log-file scan.log
--json-logs Output logs in JSON format false --json-logs
--rate-limit Requests per second limit 10 --rate-limit 5
--methods HTTP methods to test GET,POST,PUT,DELETE,PATCH --methods GET,POST
--jwt JWT token for authentication - --jwt eyJ0eXAi...
--response Filter by response codes All codes --response 200,301,404
--status-code Filter displayed results by status code or status class All codes --status-code 2xx

User Agent Options (Mutually Exclusive)

Option Description Example
--user-agent-random Use random User-Agent headers --user-agent-random
--user-agent-custom Custom User-Agent string --user-agent-custom "MyScanner/1.0"
--user-agent-file File with User-Agent strings --user-agent-file agents.txt

Advanced Options

Option Description Default Example
--detect-framework, --df Enable framework detection false --detect-framework
--fuzz-versions, --fv Enable API version fuzzing false --fuzz-versions

Discovery Control Options

These flags tune recursive discovery so you can trade breadth for speed. They keep recursion agile: stay shallow and fast for a quick sweep, or go deep and thorough when you need full coverage — always bounded by the request budget and catch-all detection.

Option Description Default Example
--depth Max recursion depth for discovery (0 = no recursion, depth-0 pass only) 3 (see precedence below) --depth 5
--recursive / --no-recursive Enable or disable recursive discovery enabled --no-recursive
--max-requests Global request budget for discovery unbounded --max-requests 5000
--concurrency Max concurrent in-flight discovery requests 50 --concurrency 100

Depth precedence. The effective recursion depth is resolved as: explicit CLI --depth > the APILEAK_MAX_DEPTH environment variable > the built-in default of 3. So --depth always wins when supplied; otherwise APILEAK_MAX_DEPTH is honored if set; otherwise depth 3 is used.

Notes.

  • --depth 0 performs only the depth-0 pass and disables recursion (equivalent to --no-recursive).
  • --max-requests defaults to unbounded; when set, it caps the total number of discovery requests across all depths.
  • --concurrency defaults to 50 concurrent in-flight requests when not specified.
  • --depth must be >= 0; --max-requests and --concurrency must be >= 1.

Proxy Options

Option Description Default Example
--proxy Route all HTTP traffic through an intercepting proxy (Burp/Caido/Hetty). Also accepts a SOCKS5 URL, optionally with auth - --proxy http://127.0.0.1:8080
--proxy-verify-ssl Keep TLS verification on when proxying (after installing the proxy CA) false --proxy-verify-ssl

SOCKS5 dependency. Routing through a SOCKS5 proxy (e.g. --proxy socks5://user:pass@host:port) requires the optional httpx[socks] extra to be installed (pip install "httpx[socks]"). Without it, SOCKS5 URLs are rejected by the underlying HTTP client. Plain http:///https:// proxies need no extra dependency.

See Proxy Integration for details.

Discovery Robustness Options

These flags harden and broaden discovery: they widen the candidate set (seeds and extensions), attach request context (headers/cookies/auth), refine which results are kept (response matchers/filters), enumerate methods and GraphQL surfaces, control per-request resilience and transport/TLS, scan responses for secrets, and emit machine-readable output. Unless noted otherwise these options apply to the dir command. The shared options -x/--extensions, --timeout, and --retries are also accepted by the scan command.

Seed Inputs and Extensions

Option Description Default Example
--wordlist, -w Wordlist file for discovery. Repeatable; values are merged and de-duplicated after normalization. Pass - to read entries from stdin (empty lines and # comment lines are skipped) wordlists/endpoints.txt -w a.txt -w b.txt / cat list.txt | ... -w -
--openapi OpenAPI/Swagger document (JSON or YAML) to seed discovery from. Repeatable - --openapi api.yaml
--postman Postman collection to seed discovery from. Repeatable - --postman collection.json
--extensions, -x File extensions appended to each wordlist entry (comma-separated, repeatable). Leading dots are optional, so -x json,php and -x .json -x .php are equivalent. Also available on scan - -x json,php

Notes:

  • Repeated --wordlist values and --openapi/--postman seeds are merged into a single candidate set with no duplicate normalized paths. If the merged candidate set is empty, the command completes without issuing any request and reports that no candidates were available.
  • An unparseable OpenAPI/Postman source is rejected with a descriptive error and no discovery is performed.
  • Each extension expands a wordlist entry into the original entry plus one candidate per distinct normalized extension (so W entries with E distinct extensions produce W × (E + 1) candidates per method). Every expanded candidate counts toward --max-requests and stays within --concurrency.

Positional Fuzz Markers (--fuzz-keyword, --fuzz-mode)

Positional fuzzing places a literal keyword directly inside the target URL and sweeps each marked position with candidate values — the ffuf/wfuzz convention. This lets you fuzz a version segment, a filename, a query-parameter value, or several positions at once, instead of only appending wordlist entries to a base path.

Option Description Default Example
--fuzz-keyword Literal token in the target URL that marks positions to fuzz. Every non-overlapping literal occurrence becomes a marker, scanned left-to-right. Matched as a plain literal (never a regex) FUZZ --fuzz-keyword FUZZ
--fuzz-mode How two or more markers combine their wordlists: clusterbomb (cartesian product) or pitchfork (index-wise pairing). Case-insensitive clusterbomb --fuzz-mode pitchfork

How markers are detected. Every literal occurrence of the keyword in the target URL is treated as a marker (a Marker_Position), scanned left-to-right and counted as the number of non-overlapping occurrences. A marker may fall inside a path segment (as a substring or a whole segment), a query-parameter name or value, a filename, or a file extension. Substitution preserves every other character, path segment, and query parameter of the target URL unchanged.

When marker mode engages. Marker mode is active whenever the target URL contains the keyword. If the target URL contains no occurrence of the keyword — and no marker-only option was supplied — dir falls back to the existing base-path behavior, appending each wordlist entry to the base path via URL join.

Per-marker wordlist association. In marker mode the repeatable --wordlist values become the per-marker wordlists, associated with markers in the left-to-right order the markers occur (the first --wordlist is the wordlist of the first marker, and so on). This differs from the non-marker merge-and-de-duplicate behavior. Fallback rules:

  • Fewer wordlists than markers: the last supplied wordlist fills every remaining marker that has no explicitly associated wordlist.
  • Exactly one wordlist, two or more markers: that single wordlist is used for every marker.
  • More wordlists than markers: rejected with a descriptive error (see below).

Combination modes. With two or more markers, --fuzz-mode controls how the per-marker wordlists combine:

  • clusterbomb (default): the cartesian product of all wordlists — every combination of one value per marker becomes a candidate. For M markers with wordlist sizes W1 … WM, this generates W1 × … × WM candidates.
  • pitchfork: the wordlists are iterated in parallel, pairing the i-th value of each list, stopping at the shortest wordlist — min(W1, …, WM) candidates. Use it to pair related lists position-by-position (e.g. a versions list with a matching filenames list).

A single marker reduces to exactly W candidates in either mode. Marker-generated candidates obey the same discovery controls as any other candidate: URL normalization and de-duplication, the --max-requests budget, the --concurrency limit, --rate-limit, the User-Agent options, the response matchers/filters, and --confirm-hits.

Choosing a distinct keyword. Because every literal occurrence of the keyword is treated as a marker, pick a keyword that does not appear in legitimate URL text. If FUZZ (or your chosen keyword) could collide with real path, query, or hostname text, choose a distinct token (for example __FUZZ__) to avoid creating unintended marker positions.

Marker-mode validation (exit-before-discovery). These configurations are rejected with a descriptive error and issue no requests:

  • An empty or whitespace-only --fuzz-keyword.
  • A marker-only option (--fuzz-keyword or --fuzz-mode given explicitly on the command line) while the target URL contains no occurrence of the keyword.
  • More --wordlist sources than there are markers (the error names both counts).
  • --fuzz-mode pitchfork with an empty associated wordlist (the error identifies the empty wordlist).
  • A --fuzz-mode value other than clusterbomb or pitchfork.
  • An associated wordlist that cannot be read from its source (the error names the unreadable source).

Request Context (Headers, Cookies, Auth)

Option Description Default Example
--header, -H Custom header applied to every discovery request, in "Name: Value" format. Repeatable - -H "X-API-Key: key123"
--cookie Raw Cookie header string applied to every discovery request - --cookie "session=abc123"
--basic-auth HTTP Basic credentials as user:pass, sent as an Authorization header on every discovery request - --basic-auth admin:secret

Notes:

  • These request-context settings are carried into the targeted follow-up scan launched from interactive triage.
  • --basic-auth and --jwt are mutually exclusive; supplying both is rejected with a descriptive error and no discovery runs.
  • A --basic-auth value without a : separating user and password is rejected with a descriptive error and no discovery runs.
  • When --load-session reloads a prior session, no requests are issued, so none of these options are applied to that run.

Response Matchers and Filters

Matchers keep only results that satisfy them; filters exclude results that satisfy them. When both are present, matchers are applied first and filters are applied to the retained set. They compose conjunctively with --status-code. All of these options are repeatable.

Option Description Example
--match-size Keep results whose response body size (bytes) satisfies the expression --match-size >100
--match-words Keep results whose response word count satisfies the expression --match-words 10-20
--match-lines Keep results whose response line count satisfies the expression --match-lines <50
--match-regex Keep results whose response body matches the regular expression --match-regex "api_key"
--match-time Keep results whose response time (seconds) satisfies the expression --match-time >2
--filter-size Exclude results whose response body size (bytes) satisfies the expression --filter-size 0
--filter-words Exclude results whose response word count satisfies the expression --filter-words <5
--filter-lines Exclude results whose response line count satisfies the expression --filter-lines 1
--filter-regex Exclude results whose response body matches the regular expression --filter-regex "Not Found"
--filter-time Exclude results whose response time (seconds) satisfies the expression --filter-time >10

Expression forms. Numeric attributes (size, words, lines, time) accept >N, <N, an inclusive range N-M, or an exact value N. The regex attributes take a regular expression matched against the response body. A syntactically invalid expression (an unparseable regex or a non-numeric bound) is rejected with a descriptive error and no discovery is performed. A soft-404 baseline is derived automatically and matching noise is suppressed independently of these selectors.

Method Enumeration and GraphQL

Option Description Default Example
--enumerate-methods After discovering an endpoint, issue an OPTIONS request and record the methods parsed from the Allow header. An absent/empty Allow records an empty set; a 405 marks the path valid under a different method false --enumerate-methods
--graphql Probe common GraphQL paths and report whether introspection is enabled (read-only introspection query). No finding is recorded when no GraphQL endpoint is found false --graphql

Both are off by default, and each extra request they issue counts toward --max-requests and stays within --concurrency.

Per-Request Resilience

These options apply to both dir and scan.

Option Description Default Example
--timeout Per-request timeout in seconds applied to every discovery request (must be > 0) 10 --timeout 30
--retries Number of automatic retries for each failed discovery request (must be >= 0) 2 --retries 5

A request exceeding --timeout is abandoned and retried up to --retries. A 429 response triggers automatic throttle/backoff that continues to honor the configured rate limit and concurrency. An invalid --timeout (not a positive number) or --retries (not a non-negative integer) is rejected with a descriptive error and no discovery is performed.

Transport and TLS

Option Description Default Example
--client-cert Client certificate for mutual TLS, presented on every request. A combined cert+key PEM path, or a cert:key pair of paths - --client-cert client.pem
--ca-bundle Custom CA bundle used to verify target certificates for every request - --ca-bundle ca.pem
--allow-cross-domain-redirects Follow redirects to other domains. By default discovery follows redirects only to the originating request's domain false --allow-cross-domain-redirects
--resolve Override DNS resolution for a host to a given IP for every request, expressed as host:ip - --resolve api.example.com:127.0.0.1

Notes:

  • A --client-cert or --ca-bundle path that does not exist or cannot be read is rejected with a descriptive error naming the path, and no discovery is performed.
  • A --resolve value not expressed as host:ip is rejected with a descriptive error naming the value, and no discovery is performed.
  • SOCKS5 proxies are supplied through the existing --proxy flag and require the httpx[socks] extra (see the Proxy Options note above).

Secret and Leak Detection

Option Description Default Example
--detect-secrets Scan each discovery response body and headers for secrets/leaked credentials (read-only). Matched values are redacted in output false --detect-secrets
--secret-patterns Path to a JSON file mapping pattern names to regex strings used for secret detection. Defaults to the built-in patterns when omitted built-in patterns --secret-patterns patterns.json

Secret detection is off by default. When enabled, a response with no matching content yields no finding; a match is tagged to the endpoint whose response contained it, with the matched value redacted.

Machine-Readable Output

Option Description Default Example
--output-format Write a machine-readable discovery output in the selected format (csv or jsonl) - --output-format jsonl
--output-file Destination path for the machine-readable output (the extension selects the format) - --output-file results.jsonl

Records are ordered consistently with the triage table, grouped by status class in ascending order. An unsupported format is rejected with a descriptive error and writes no file; a write failure on an unwritable path also errors. This is distinct from --export/--export-file, which produce a human-readable md/txt report.

Path and Status Scope (Storage-Time Selection)

These options decide which discovered records are ever persisted, applied at discovery time as a record is recorded. They are distinct from the display-only --status-code filter and the --match-*/--filter-* selectors, which act on records that have already been stored.

Option Description Default Example
--include-path Only persist discovered endpoints whose path or URL matches the regular expression. Repeatable - --include-path "^/api/"
--exclude-path Never persist discovered endpoints whose path or URL matches the regular expression. Repeatable; takes precedence over --include-path - --exclude-path "\.png$"
--include-status Only persist discovered endpoints whose status matches the selection — a status class (2xx) or explicit codes/ranges (200,404 or 200-300) - --include-status 2xx
--exclude-status Never persist discovered endpoints whose status matches the selection; takes precedence over --include-status - --exclude-status 404

Exclude precedence (path). A candidate path or URL matching any --exclude-path pattern is neither tested nor stored, regardless of which --include-path patterns it also matches. When one or more --include-path patterns are supplied, a candidate must match at least one of them to be kept; with no include patterns, everything not excluded is kept.

Exclude precedence (status). A record whose status matches --exclude-status is dropped even if it also matches --include-status. With no --include-status, every status not excluded is kept.

Storage vs. display. These are storage-time decisions: a record dropped here never enters the discovery session file (--save-session), the machine-readable output (--output-format), or the triage table — regardless of any later display-only --status-code value. By contrast, --status-code, --match-*, and --filter-* only change which already-stored records are shown.

Validation. An --include-path/--exclude-path value that is not a valid regular expression, or an --include-status/--exclude-status value that is an explicit code outside 100-599 or a token that is neither a status class nor an explicit code, is rejected with a descriptive error naming the offending value, and no discovery is performed.

Recursion Scope

These options narrow which discovered endpoints recursion descends into. They are accepted by both dir and scan. They only ever narrow the default VALID/AUTH_REQUIRED recursion eligibility — they never relax it.

Option Description Default Example
--recursion-status Restrict recursion to endpoints whose status class is in the comma-separated list of status classes (2xx,3xx) - --recursion-status 2xx,3xx
--recursion-type Restrict recursion to endpoints whose type is in the comma-separated list of endpoint types (admin, api_version, authentication, development, standard) - --recursion-type admin,api_version

Notes:

  • When a recursion-scope option is supplied, only discovered records that satisfy every supplied selection are recursed into; the set recursed into is always a subset of the records that already satisfy the default recursion eligibility (VALID or AUTH_REQUIRED and not a catch-all response).
  • Recursion still respects --depth, --max-requests (every recursive request counts toward the budget), --concurrency, and catch-all suppression.
  • With no recursion-scope option, the existing recursion behavior is preserved unchanged.
  • A --recursion-status status class or --recursion-type endpoint type that is not recognized is rejected with a descriptive error naming the value, and no discovery is performed.

Hit Confirmation

Option Description Default Example
--confirm-hits Enable Hit_Confirmation: re-request each interesting candidate N times and record it only when the responses are consistent (must be >= 1) off --confirm-hits 3

Hit confirmation is off by default. When enabled, each candidate interesting result is re-requested N times and is recorded only when the confirmation responses are consistent — meaning they share the same status class and a comparable response body size. Inconsistent (flaky or randomized) responses are not recorded, which reduces false positives. Each confirmation request counts toward --max-requests, stays within --concurrency, and honors the configured --rate-limit. A --confirm-hits value that is not an integer >= 1 is rejected with a descriptive error, and no discovery is performed.

Checkpoint and Resume

Option Description Default Example
--checkpoint Periodically write a discovery checkpoint to PATH so an interrupted run can be resumed (atomic writes) - --checkpoint scan.ckpt
--resume Resume an interrupted discovery run from the checkpoint at PATH (loaded before discovery) - --resume scan.ckpt

Checkpoint/resume contract:

  • Checkpointing. With --checkpoint, discovery periodically writes a checkpoint recording the candidates already tested and the results discovered so far. Writes are atomic (a temporary file is written then moved into place), so a failure never leaves a partially written checkpoint. A checkpoint path that cannot be written is rejected with a descriptive error.
  • Resuming. With --resume, the checkpoint is loaded before any discovery runs. Candidates recorded as already tested are treated as tested and are not re-requested (no-recompute), and the checkpointed results are merged with newly discovered ones so the union contains no two records sharing the same (url, method) pair (no-duplication).
  • Combine them. Pass both --resume and --checkpoint to resume a run and keep checkpointing it.
  • Validation. A --resume checkpoint that does not exist, cannot be read, or cannot be parsed into the expected checkpoint structure is rejected with a descriptive error naming the artifact, and no discovery is performed.
  • Separate from sessions. The discovery checkpoint is a distinct artifact from the --save-session/--load-session session file; it additionally records the in-flight tested candidates and is intended for resuming, not for triage reload.

Discovery Triage Options

The triage workflow is an additive layer on top of discovery. It is engaged automatically when you pass any of the flags below; otherwise dir behaves exactly as before. Discovered endpoints are projected into DiscoveryResult records (URL, method, status code, EndpointStatus) that can be grouped/filtered by status class, rendered as a rich table, saved to a structured session file, exported in a human-readable form, and used to drive an opt-in follow-up scan.

Option Description Default Example
--save-session Save all discovery results to a JSON session file (the source of truth for reload) - --save-session session.json
--load-session Reload discovery results exclusively from a JSON session file (skips discovery) - --load-session session.json
--export Write a human-readable export in the selected format (md or txt) - --export md
--export-file Destination path for the human-readable export (the extension selects the format) reports/discovery_export.<fmt> --export-file results.md
--interactive, --triage Enable interactive triage mode (opt-in; auto-disabled in CI mode) false --interactive
--scan-scope Non-interactively select a batch of discovered records (2xx/3xx/4xx/5xx/valid/auth_required) and run an OWASP scan over them - --scan-scope valid
--ci-mode Enable CI mode; disables the interactive prompt so it never blocks a pipeline false --ci-mode

Key behaviors:

  • Session file is the source of truth. --load-session reads records only from the JSON session file; the human-readable export is never read back.
  • Atomic session writes. A failed --save-session never leaves a partially written file, and surfaces a descriptive error.
  • Triage table. Results render in a four-column table — URL, Method, Status, EndpointStatus — grouped by status class in ascending order (2xx, 3xx, 4xx, 5xx). An empty/filtered-to-empty result set shows the header row with zero data rows.
  • Export grouping. The .md/.txt export groups records by status class in the same ascending order. Any format other than .md/.txt is rejected with a descriptive error and writes nothing.
  • Interactive mode is opt-in and CI-safe. It is off by default, prompts for exactly one endpoint when enabled, re-prompts on invalid input up to 3 consecutive attempts (then abandons without a scan), and is automatically disabled under --ci-mode so it never blocks.

Discovery-to-Scan Integration (Batch Scan Scope)

Discovery can feed an OWASP scan directly over a set of discovered endpoints, so you don't have to launch a single-endpoint follow-up for each result. The batch scope can be selected interactively or non-interactively.

  • Interactive multi-select. In interactive triage (--interactive), entering two or more record indices — a comma list like 1,3,5 or a range like 2-4 — selects a batch scan scope and runs an OWASP scan over exactly those records. A single index keeps the existing single-endpoint follow-up.
  • Non-interactive --scan-scope. --scan-scope <2xx|3xx|4xx|5xx|valid|auth_required> selects all discovered records of the chosen status class or EndpointStatus (valid selects all VALID records, auth_required selects all AUTH_REQUIRED records) and runs an OWASP scan over them through the scan command engine path.
  • CI-only non-interactive. Under --ci-mode the batch scope is determined only from --scan-scope; the interactive selection prompt never runs and never blocks the pipeline.
  • Inherited request settings. The batch scan applies the same --rate-limit, User-Agent option, and --header/--cookie/--basic-auth request context supplied to the originating dir invocation.
  • Empty scope. If the determined scope is empty (no records match the token, or an empty multi-select), no scan runs and the command reports that there is nothing to scan.
  • Invalid token. A --scan-scope value that is neither a recognized status class nor a recognized EndpointStatus is rejected with a descriptive error naming the value, and no scan runs.

Status Code Filtering

The --status-code flag accepts three forms in triage mode (parsed by parse_status_filter):

Form Example Meaning
Status class token 2xx, 3xx, 4xx, 5xx (case-insensitive) Keep records whose status code shares that leading digit
Explicit codes 200,404,500 Keep records whose status code is exactly in the set
Ranges 200-299, 400-403 Keep records whose status code falls in the range

Notes:

  • A class token is single-valued — use 2xx on its own, not 2xx,404.
  • Explicit codes are validated to the inclusive range 100-599; an out-of-range value (e.g. 700) is rejected with an error naming the offending value and exits non-zero.
  • Records whose leading digit is not 2-5 (for example a 1xx) are excluded from all status-class groups.

Examples

The dir command's usage examples are organized into three levels: basic uses, intermediate uses, and advanced uses. Each example includes a title, a short description of what it does and what it's for, and a ready-to-copy command. The more flags you combine, the closer the example gets to the advanced level.


Basic uses

Minimal examples to start discovering endpoints. They cover the target, the wordlist, HTTP methods, simple authentication, request pacing, and the output report name.

1. Basic discovery

Runs endpoint fuzzing against the target using the default wordlist (wordlists/endpoints.txt). It's the starting point for any reconnaissance.

python apileaks.py dir --target https://api.example.com

2. Custom wordlist

Uses your own list of candidate paths instead of the default wordlist. Useful when you have a dictionary specific to the target's domain or technology.

python apileaks.py dir \
  --target https://api.example.com \
  --wordlist custom_endpoints.txt

3. Restrict the HTTP methods tested

Restricts which HTTP verbs are tested on each candidate. Reduces the number of requests and the noise when you only care about certain methods.

python apileaks.py dir \
  --target https://api.example.com \
  --methods GET,POST

4. Request pacing (rate limit)

Lowers the requests-per-second rate to be stealthier or avoid overwhelming the target. The default is 10 req/s.

python apileaks.py dir \
  --target https://api.example.com \
  --rate-limit 5

5. Authenticated discovery with a JWT

Attaches a JWT as a credential to discover endpoints that are only visible after authenticating.

python apileaks.py dir \
  --target https://api.example.com \
  --jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

6. Filter results by status code

Shows only the results whose status matches a class (2xx), explicit codes (200,401,403), or a range (400-403).

# Only successful responses (status class)
python apileaks.py dir \
  --target https://api.example.com \
  --status-code 2xx

# Explicit codes
python apileaks.py dir \
  --target https://api.example.com \
  --status-code 200,401,403

# A range of codes
python apileaks.py dir \
  --target https://api.example.com \
  --status-code 400-403

7. Name the output file

Sets the base name of the generated report instead of letting it be auto-generated.

python apileaks.py dir \
  --target https://api.example.com \
  --output my-recon

Intermediate uses

Examples that combine several discovery sources, request context, recursion control, and result persistence. These are the flags you'll use in a realistic reconnaissance.

1. Multiple wordlists and extensions

Merges several wordlists (de-duplicated after normalization) and expands each entry with file extensions. -w and -x are repeatable.

python apileaks.py dir \
  --target https://api.example.com \
  -w wordlists/endpoints.txt \
  -w wordlists/admin.txt \
  -x json,php

2. Seed discovery from OpenAPI / Postman

Feeds discovery with paths extracted from an OpenAPI/Swagger spec or a Postman collection. Both flags are repeatable and combine with the wordlists.

python apileaks.py dir \
  --target https://api.example.com \
  --openapi api.yaml \
  --postman collection.json

3. Request context: headers, cookies, and Basic Auth

Attaches custom headers, a cookie, or HTTP Basic credentials to every discovery request. -H is repeatable.

python apileaks.py dir \
  --target https://api.example.com \
  -H "X-API-Key: key123" \
  -H "X-Env: staging" \
  --cookie "session=abc123" \
  --basic-auth admin:secret

4. Framework detection and version fuzzing

Detects the backend framework while fuzzing and enumerates API versions (/v1, /v2, /api/v1, ...). You can use them separately or together.

# Framework detection only
python apileaks.py dir \
  --target https://api.example.com \
  --detect-framework

# Framework detection + version fuzzing
python apileaks.py dir \
  --target https://api.example.com \
  --detect-framework \
  --fuzz-versions

5. User-Agent rotation (WAF evasion)

Changes the User-Agent to make detection harder. The three options are mutually exclusive: random, a fixed one, or rotation from a file.

# Random User-Agent from the built-in set
python apileaks.py dir \
  --target https://api.example.com \
  --user-agent-random

# A fixed User-Agent
python apileaks.py dir \
  --target https://api.example.com \
  --user-agent-custom "MyScanner/1.0"

# Round-robin rotation from a file
python apileaks.py dir \
  --target https://api.example.com \
  --user-agent-file user_agents.txt

6. Recursion control (depth, budget, concurrency)

Tunes how deep discovery recurses, the total request budget, and how many run in parallel. Lets you balance coverage against speed.

python apileaks.py dir \
  --target https://api.example.com \
  --depth 5 \
  --max-requests 5000 \
  --concurrency 100

7. Per-request resilience (timeout and retries)

Sets the per-request timeout and how many automatic retries to make on failure. Also accepted by scan.

python apileaks.py dir \
  --target https://api.example.com \
  --timeout 30 \
  --retries 5

8. Session persistence and reload

Saves the full result set to a session file (the source of truth) and reloads it later without re-running discovery.

# Save the session
python apileaks.py dir \
  --target https://api.example.com \
  --save-session session.json

# Reload the session (skips discovery) and filter to server errors
python apileaks.py dir \
  --target https://api.example.com \
  --load-session session.json \
  --status-code 5xx

9. Human-readable export (Markdown / text)

Generates a readable report grouped by status class, in md or txt. You can save the session and export in the same run.

python apileaks.py dir \
  --target https://api.example.com \
  --save-session session.json \
  --export md \
  --export-file results.md

10. Machine-readable output (CSV / JSONL)

Writes a machine-processable output in csv or jsonl, distinct from the human-readable export. The file extension selects the format.

python apileaks.py dir \
  --target https://api.example.com \
  --output-format jsonl \
  --output-file results.jsonl

11. Route through an intercepting proxy (Burp / Caido / Hetty)

Sends all traffic through a proxy to inspect and replay requests. Also accepts SOCKS5 URLs (requires httpx[socks]).

python apileaks.py dir \
  --target https://api.example.com \
  --proxy http://127.0.0.1:8080

Advanced uses

Examples that exploit the discovery engine's fine-grained capabilities: positional fuzzing, matchers/filters, method and GraphQL probing, secret detection, storage and recursion scope, hit confirmation, checkpoint/resume, TLS, interactive triage, and integration with the OWASP scan.

1. Positional fuzzing with markers (clusterbomb / pitchfork)

Places a literal keyword inside the target URL and sweeps each marked position with candidate values (ffuf/wfuzz convention). With multiple markers, --fuzz-mode controls how the wordlists combine.

# One marker in the version segment
python apileaks.py dir \
  --target "https://api.example.com/FUZZ/users" \
  --fuzz-keyword FUZZ \
  -w versions.txt

# Two markers, cartesian product (clusterbomb)
python apileaks.py dir \
  --target "https://api.example.com/FUZZ/FUZZ" \
  --fuzz-keyword FUZZ \
  --fuzz-mode clusterbomb \
  -w versions.txt \
  -w endpoints.txt

# Two markers paired position-by-position (pitchfork)
python apileaks.py dir \
  --target "https://api.example.com/__FUZZ__/__FUZZ__" \
  --fuzz-keyword __FUZZ__ \
  --fuzz-mode pitchfork \
  -w versions.txt \
  -w filenames.txt

2. Response matchers and filters

Keeps (--match-*) or excludes (--filter-*) results by size, words, lines, time, or a body regex. All are repeatable and compose with --status-code.

python apileaks.py dir \
  --target https://api.example.com \
  --match-size ">100" \
  --match-regex "api_key" \
  --filter-regex "Not Found" \
  --filter-size 0

3. Method enumeration and GraphQL probing

After discovering an endpoint, issues OPTIONS to record the methods from the Allow header, and probes common GraphQL paths reporting whether introspection is enabled.

python apileaks.py dir \
  --target https://api.example.com \
  --enumerate-methods \
  --graphql

4. Secret and leaked-credential detection

Scans each response body and headers for secrets (read-only). Matched values are redacted in the output. You can supply your own patterns.

python apileaks.py dir \
  --target https://api.example.com \
  --detect-secrets \
  --secret-patterns patterns.json

5. Path and status scope (storage-time selection)

Decides which records ever get persisted. Exclude patterns take precedence over include patterns. Unlike --status-code, this acts before storing.

python apileaks.py dir \
  --target https://api.example.com \
  --include-path "^/api/" \
  --exclude-path "\.png$" \
  --include-status 2xx \
  --exclude-status 404

6. Recursion scope

Restricts which endpoints recursion descends into, by status class and/or endpoint type. It only narrows the default eligibility, never relaxes it.

python apileaks.py dir \
  --target https://api.example.com \
  --recursion-status 2xx,3xx \
  --recursion-type admin,api_version

7. Hit confirmation (reduce false positives)

Re-requests each interesting candidate N times and only records it if the responses are consistent (same status class and comparable size).

python apileaks.py dir \
  --target https://api.example.com \
  --confirm-hits 3

8. Checkpoint and resume

Writes periodic checkpoints (atomic writes) so an interrupted discovery can be resumed. Combine --resume and --checkpoint to resume and keep saving.

# Run while saving checkpoints
python apileaks.py dir \
  --target https://api.example.com \
  --checkpoint scan.ckpt

# Resume from the checkpoint and keep saving
python apileaks.py dir \
  --target https://api.example.com \
  --resume scan.ckpt \
  --checkpoint scan.ckpt

9. Transport and TLS (mTLS, custom CA, DNS, redirects)

Presents a client certificate for mTLS, verifies with a custom CA, overrides DNS resolution, and allows cross-domain redirects.

python apileaks.py dir \
  --target https://api.example.com \
  --client-cert client.pem \
  --ca-bundle ca.pem \
  --resolve api.example.com:127.0.0.1 \
  --allow-cross-domain-redirects

10. Interactive triage and targeted follow-up

Enables the interactive triage table (opt-in). Selecting an endpoint launches a follow-up scan that inherits the rate limit, User-Agent, and request context. --triage is an alias for --interactive.

python apileaks.py dir \
  --target https://api.example.com \
  --load-session session.json \
  --status-code 2xx \
  --interactive

11. Discovery-to-scan integration (batch scan)

Feeds an OWASP scan directly over a batch of discovered endpoints, non-interactively, selecting by status class or EndpointStatus.

python apileaks.py dir \
  --target https://api.example.com \
  --scan-scope valid

12. CI/CD-safe run

CI mode disables the interactive prompt so it never blocks the pipeline, even if --interactive is passed. Combine it with --scan-scope for non-interactive batch scanning.

python apileaks.py dir \
  --target https://api.example.com \
  --interactive \
  --ci-mode \
  --scan-scope valid \
  --save-session session.json \
  --export md \
  --export-file results.md

13. Combining rate limit + User-Agent with recursion and triage

--rate-limit and the User-Agent options apply to every request and are inherited by the targeted follow-up. Here they're combined with bounded recursion and interactive triage.

python apileaks.py dir \
  --target https://api.example.com \
  --rate-limit 10 \
  --user-agent-file user_agents.txt \
  --depth 5 \
  --max-requests 8000 \
  --save-session session.json \
  --interactive

14. Full triage workflow (all in one invocation)

Discover, detect framework, filter to successful endpoints, save the session, export Markdown, and open the interactive prompt — all in a single command.

python apileaks.py dir \
  --target https://api.example.com \
  --wordlist wordlists/endpoints.txt \
  --rate-limit 10 \
  --detect-framework \
  --status-code 2xx \
  --save-session session.json \
  --export md \
  --export-file discovery.md \
  --interactive

Rate Limiting and User-Agent in Discovery and Triage

--rate-limit and the three User-Agent options apply to every discovery request the dir command issues, and they compose freely with the discovery-control and triage flags (--depth, --max-requests, --save-session, --status-code, --interactive). The same settings are also inherited by the targeted follow-up scan launched from interactive triage (see notes below).

Rate limit + each User-Agent option, combined with discovery/triage flags

# Random User-Agent rotation + gentle rate limit, bounded recursive discovery,
# saving a session for later triage
python apileaks.py dir \
  --target https://api.example.com \
  --rate-limit 5 \
  --user-agent-random \
  --depth 4 \
  --max-requests 5000 \
  --status-code 2xx \
  --save-session session.json

# Custom (single) User-Agent + rate limit, with interactive triage so the
# follow-up scan inherits both settings
python apileaks.py dir \
  --target https://api.example.com \
  --rate-limit 8 \
  --user-agent-custom "MyScanner/1.0" \
  --status-code 2xx \
  --save-session session.json \
  --interactive

# Rotating User-Agents from a file + rate limit, deep discovery with a budget,
# saving a session and opening interactive triage
python apileaks.py dir \
  --target https://api.example.com \
  --rate-limit 10 \
  --user-agent-file user_agents.txt \
  --depth 5 \
  --max-requests 8000 \
  --save-session session.json \
  --interactive

Notes.

  • Mutually exclusive User-Agent options. Exactly one of --user-agent-random, --user-agent-custom "<UA>", or --user-agent-file <list.txt> may be supplied per invocation. Passing more than one is rejected with an error that names the conflict, and no discovery is performed.
  • --user-agent-custom uses the single supplied string as the User-Agent for every discovery request.
  • --user-agent-random picks a User-Agent at random from the built-in set for each discovery request.
  • --user-agent-file loads User-Agents from the file, one per line; empty lines and lines whose first non-whitespace character is # (comments) are skipped. The loaded strings are then rotated in round-robin order across discovery requests. A missing or unreadable file path is rejected with an error naming the path, and no discovery is performed.
  • --rate-limit applies only to requests actually issued. When --load-session reloads a prior session, no discovery requests are made, so the rate limit is not applied to that run.
  • Targeted follow-up inherits these settings. The Targeted_Follow_Up_Scan launched from interactive triage reuses the same --rate-limit and User-Agent option (random / custom / file) from the originating dir invocation, applying them to every request it issues. A --user-agent-file list is reloaded and rotated for the follow-up the same way.

Parameter Fuzzing (par)

Discover hidden, undocumented, or debug parameters accepted by an API endpoint. The par command injects candidate parameter names from a wordlist and compares responses against a baseline to detect parameters that alter application behavior. See the Parameter Fuzzing Guide for a comprehensive walkthrough.

Syntax

python apileaks.py par [OPTIONS]

Required Options

Option Description Example
--target, -t Target URL to scan --target https://api.example.com/users

Core Parameter Fuzzing Options

Option Description Default Example
--wordlist, -w Wordlist file (repeatable, merged/deduped). Use - for stdin wordlists/parameters.txt --wordlist params.txt
--methods HTTP methods to test (comma-separated: GET,POST,PUT,PATCH,DELETE). Controls injection points: GET/DELETE → query, POST/PUT/PATCH → body GET,POST --methods POST,PUT
--confirm-hits Re-test each candidate N times to confirm (≥1). Only stable hits are reported Off --confirm-hits 3
--max-requests Request budget: stop after N total requests (≥1) Unbounded --max-requests 1000

Request Context Options

Option Description Default Example
-H, --header Custom header (repeatable, Name: Value format) -H "X-API-Key: abc"
--cookie Cookie value (sent as Cookie header) --cookie "session=xyz"
--basic-auth Basic authentication (user:pass) --basic-auth admin:secret
--jwt JWT bearer token --jwt eyJ0eXAi...

Resilience and Concurrency Options

Option Description Default Example
--timeout Per-request timeout in seconds (>0) Same as dir --timeout 20
--retries Retry count for failed requests (≥0) Same as dir --retries 3
--concurrency Max in-flight requests (≥1) Same as dir --concurrency 50
--rate-limit Requests per second limit 10 --rate-limit 5

TLS Transport Options

Option Description Default Example
--client-cert Client TLS certificate path --client-cert client.pem
--ca-bundle Custom CA bundle path --ca-bundle ca.pem
--resolve DNS resolution override (host:ip) --resolve api.example.com:10.0.1.50

Matcher/Filter Options

Response matchers retain findings; filters exclude them. Matchers are applied before filters, consistent with dir.

Option Description Example
--match-size Keep findings by response size --match-size ">100"
--match-words Keep findings by word count --match-words ">10"
--match-lines Keep findings by line count --match-lines ">5"
--match-regex Keep findings matching regex --match-regex "admin"
--match-time Keep findings by response time --match-time ">2.0"
--filter-size Exclude findings by response size --filter-size "<50"
--filter-words Exclude findings by word count --filter-words "<3"
--filter-lines Exclude findings by line count --filter-lines "<2"
--filter-regex Exclude findings matching regex --filter-regex "Not Found"
--filter-time Exclude findings by response time --filter-time "<0.1"

Machine-Readable Output Options

Option Description Default Example
--output-format Output format (csv or jsonl) --output-format jsonl
--output-file Output file path --output-file findings.jsonl

General Options

Option Description Default Example
--output, -o Report filename prefix Auto-generated --output param-scan
--log-level Logging level WARNING --log-level INFO
--log-file Log file path Console only --log-file param.log
--json-logs Output logs in JSON format false --json-logs
--response Filter by response codes (legacy) All codes --response 200,400
--status-code Show only specific status codes All codes --status-code 200,500-599
--proxy HTTP/SOCKS proxy URL --proxy http://127.0.0.1:8080

Finding Severity and SSRF Escalation

par reports all discovered parameters as PARAMETER_FOUND. Severity is set based on the parameter name:

Condition Severity OWASP When
Generic parameter name INFO Default for any discovered parameter
Name contains URL keyword (url, uri, host, endpoint, target, webhook, callback, redirect, src, source, feed, imageUrl, etc.) MEDIUM API7 Parameter likely carries a URL → potential SSRF surface

When a MEDIUM finding is reported, the recommendation includes a ready-to-use SSRF test payload so the operator can immediately follow up with owasp ssrf. | --proxy-verify-ssl | Keep TLS verification with proxy | Off | --proxy-verify-ssl | | --no-banner | Suppress startup banner | Off | --no-banner |

User Agent Options (Mutually Exclusive)

Same as directory fuzzing — see above.

Advanced Options

Option Description Default Example
--detect-framework, --df Enable framework detection false --detect-framework

Basic Examples

# Discover hidden parameters using the default wordlist
python apileaks.py par --target https://api.example.com/users/123

# With authentication and custom wordlist
python apileaks.py par \
  --target https://api.example.com/api/v1/users \
  --jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  --wordlist custom_parameters.txt

# Fuzz only POST body parameters
python apileaks.py par \
  --target https://api.example.com/api/v1/orders \
  --methods POST

# Limit total requests
python apileaks.py par \
  --target https://api.example.com/search \
  --max-requests 500

Intermediate Examples

# Hit confirmation to reduce false positives
python apileaks.py par \
  --target https://api.example.com/api/v1/search \
  --confirm-hits 3 \
  --max-requests 1500

# Multiple wordlists merged and deduped
python apileaks.py par \
  --target https://api.example.com/api/v1/users \
  --wordlist wordlists/parameters.txt \
  --wordlist wordlists/admin_params.txt

# Request context: headers, cookie, and basic auth
python apileaks.py par \
  --target https://internal-api.example.com/config \
  -H "X-Tenant: acme" \
  --cookie "session=abc123" \
  --basic-auth admin:s3cr3t

# Resilience against a slow target
python apileaks.py par \
  --target https://slow-api.example.com/endpoint \
  --timeout 30 \
  --retries 3 \
  --rate-limit 3

Advanced Examples

# Full-featured scan: auth, confirmation, budget, matchers, machine output
python apileaks.py par \
  --target https://api.example.com/api/v1/users/me \
  --jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -H "X-Correlation-ID: pentest-001" \
  --wordlist wordlists/parameters.txt \
  --wordlist wordlists/debug_params.txt \
  --methods GET,POST \
  --confirm-hits 3 \
  --max-requests 2000 \
  --rate-limit 10 \
  --timeout 20 \
  --concurrency 25 \
  --match-size ">100" \
  --filter-regex "Not Found" \
  --output-format jsonl \
  --output-file reports/par_findings.jsonl

# Mutual TLS + DNS override for internal APIs
python apileaks.py par \
  --target https://internal-api.example.com/admin \
  --client-cert certs/client.pem \
  --ca-bundle certs/internal-ca.pem \
  --resolve internal-api.example.com:10.0.1.50 \
  --basic-auth auditor:pass

# CI pipeline: bounded, quiet, machine-readable
python apileaks.py par \
  --target "${API_ENDPOINT}" \
  --jwt "${JWT_TOKEN}" \
  --max-requests 1000 \
  --confirm-hits 2 \
  --output-format jsonl \
  --output-file reports/par_ci.jsonl \
  --no-banner

# WAF evasion with random user agents
python apileaks.py par \
  --target https://protected-api.example.com/endpoint \
  --user-agent-random \
  --rate-limit 3 \
  --timeout 20

# Through an intercepting proxy (Burp/Caido)
python apileaks.py par \
  --target https://api.example.com/api/v1/orders \
  --proxy http://127.0.0.1:8080 \
  --jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

Security Scan (scan)

The scan command is APILeak's primary orchestrator. It runs endpoint discovery and then executes all registered OWASP API Security Top 10 modules by default, aggregating every finding through the unified reporting pipeline and driving the CI/CD severity gate. Use --modules a,b to restrict the run to selected module keys.

To run a single OWASP module in isolation (red-team focus), use the owasp <key> command instead.

Deprecation. full and main are deprecated, hidden aliases of scan. They forward to scan unchanged (emitting a one-line stderr deprecation notice) and are retained only for backward compatibility — migrate scripts to scan. A single-module alias invocation such as full --modules bola should become apileaks owasp bola.

Syntax

python apileaks.py scan [OPTIONS]

Required Options

Option Description Example
--target, -t Target URL to scan (required if no config) --target https://api.example.com

Configuration Options

Option Description Example
--config, -c Configuration file path (YAML/JSON) --config config/api.yaml

Basic Options

Option Description Default Example
--output, -o Output filename for reports Auto-generated --output comprehensive-scan
--log-level Logging level WARNING --log-level INFO
--log-file Log file path Console only --log-file full-scan.log
--json-logs Output logs in JSON format false --json-logs
--rate-limit Requests per second limit 10 --rate-limit 15
--jwt JWT token for authentication - --jwt eyJ0eXAi...
--status-code Show only specific status codes All codes --status-code 200,401,403

OWASP Module Selection

Option Description Default Example
--modules Comma-separated OWASP modules All modules --modules bola,auth,property

Available modules:

  • bola - BOLA (Broken Object Level Authorization) testing — API1
  • auth - Authentication testing (JWT vulnerabilities) — API2
  • property - Property Level Authorization testing — API3
  • resource - Unrestricted Resource Consumption testing — API4
  • function_auth - Function Level Authorization testing — API5
  • business_flow - Unrestricted Access to Sensitive Business Flows — API6
  • ssrf - Server-Side Request Forgery testing — API7
  • security_misconfig - Security Misconfiguration (CORS, missing headers) — API8
  • inventory - Improper Inventory Management (deprecated/undocumented versions) — API9
  • unsafe_consumption - Unsafe Consumption of APIs — API10

User Agent Options (Mutually Exclusive)

Same as directory fuzzing - see above.

Advanced Discovery Features

Option Description Default Example
--detect-framework, --df Enable framework detection false --detect-framework
--fuzz-versions, --fv Enable API version fuzzing false --fuzz-versions
--framework-confidence Framework detection confidence 0.6 --framework-confidence 0.8
--version-patterns Custom version patterns Default patterns --version-patterns /v1,/v2,/api/v1
--enable-advanced Enable all advanced features false --enable-advanced
--enable-payload-encoding Enable payload encoding/obfuscation false --enable-payload-encoding
--enable-waf-evasion Enable WAF detection and evasion false --enable-waf-evasion
--enable-subdomain-discovery Enable subdomain discovery false --enable-subdomain-discovery
--enable-cors-analysis Enable CORS analysis false --enable-cors-analysis

Discovery Control Options

These flags tune recursive discovery so you can trade breadth for speed. They keep recursion agile: stay shallow and fast for a quick sweep, or go deep and thorough when you need full coverage — always bounded by the request budget and catch-all detection.

Option Description Default Example
--depth Max recursion depth for discovery (0 = no recursion, depth-0 pass only) 3 (see precedence below) --depth 5
--recursive / --no-recursive Enable or disable recursive discovery enabled --no-recursive
--max-requests Global request budget for discovery unbounded --max-requests 5000
--concurrency Max concurrent in-flight discovery requests 50 --concurrency 100

Depth precedence. The effective recursion depth is resolved as: explicit CLI --depth > the APILEAK_MAX_DEPTH environment variable > the built-in default of 3. So --depth always wins when supplied; otherwise APILEAK_MAX_DEPTH is honored if set; otherwise depth 3 is used.

Notes.

  • --depth 0 performs only the depth-0 pass and disables recursion (equivalent to --no-recursive).
  • --max-requests defaults to unbounded; when set, it caps the total number of discovery requests across all depths.
  • --concurrency defaults to 50 concurrent in-flight requests when not specified.
  • --depth must be >= 0; --max-requests and --concurrency must be >= 1.

Recursion Scope

The scan command accepts the same recursion-scope options as dir to narrow which discovered endpoints recursion descends into. They only narrow the default VALID/AUTH_REQUIRED recursion; they never relax it.

Option Description Default Example
--recursion-status Restrict recursion to endpoints whose status class is in the comma-separated list of status classes (2xx,3xx) - --recursion-status 2xx,3xx
--recursion-type Restrict recursion to endpoints whose type is in the comma-separated list of endpoint types (admin, api_version, authentication, development, standard) - --recursion-type admin,api_version

An unrecognized --recursion-status status class or --recursion-type endpoint type is rejected with a descriptive error naming the value, and no discovery is performed. See the dir command's Recursion Scope notes for the full behavior.

Discovery Robustness Options

The scan command shares the discovery seed and per-request resilience controls described in detail under the dir command's Discovery Robustness Options. The following are accepted by scan:

Option Description Default Example
--extensions, -x File extensions appended to each wordlist entry (comma-separated, repeatable; leading dots optional) - -x json,php
--timeout Per-request timeout in seconds applied to every discovery request (must be > 0) 10 --timeout 30
--retries Number of automatic retries for each failed discovery request (must be >= 0) 2 --retries 5

Invalid --timeout or --retries values are rejected with a descriptive error before any discovery runs. The richer request-context, response-matcher/filter, GraphQL, transport/TLS, secret-detection, and machine-readable-output options are specific to the dir command.

CI/CD Integration

Option Description Default Example
--ci-mode Enable CI/CD mode with deterministic exit codes and artifact generation false --ci-mode
--fail-on Fail on findings of this severity or higher high --fail-on high
--sarif Generate a SARIF 2.1.0 report (for code scanning / CI integration) false --sarif
--safe-mode Non-destructive scan: skip state-changing probes (POST/PUT/PATCH/DELETE) and restrict to safe methods false --safe-mode
--baseline Path to a baseline JSON report; only new findings drive the severity gate (missing path treats all findings as new) - --baseline baseline.json

Available severity levels: critical, high, medium, low

Default gate. The severity gate default is now high (it was previously critical). Runs without an explicit --fail-on fail on high or critical findings. Pass --fail-on critical to keep the old behavior.

Examples

The scan command's usage examples are organized into three levels: basic uses, intermediate uses, and advanced uses. Each example includes a title, a short description of what it does and what it's for, and a ready-to-copy command. Remember that a plain scan already runs discovery plus all ten OWASP API Security Top 10 modules; the more flags you combine, the closer the example gets to the advanced level.


Basic uses

Minimal examples to run an orchestrated assessment. They cover the target, authentication, module selection, the output report name, status filtering, request pacing, and using a config file.

1. Basic scan

Runs endpoint discovery followed by all ten OWASP modules by default, aggregating every finding into one report. It's the starting point for a full-coverage assessment.

python apileaks.py scan --target https://api.example.com

2. Authenticated scan with a JWT

Attaches a JWT so discovery and every OWASP module test the target as an authenticated user.

python apileaks.py scan \
  --target https://api.example.com \
  --jwt "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

3. Restrict to specific OWASP modules

Limits the run to a subset of modules instead of all ten, aggregating their findings into a single report.

python apileaks.py scan \
  --target https://api.example.com \
  --modules bola,auth,property

4. Name the output report

Sets the base name of the generated report instead of letting it be auto-generated.

python apileaks.py scan \
  --target https://api.example.com \
  --output comprehensive-scan

5. Filter shown status codes

Shows only responses matching the given codes/ranges, reducing noise during the run.

python apileaks.py scan \
  --target https://api.example.com \
  --status-code 200,401,403

6. Adjust request pacing (rate limit)

Raises or lowers the requests-per-second rate for the whole scan. The default is 10 req/s.

python apileaks.py scan \
  --target https://api.example.com \
  --rate-limit 15

7. Use a configuration file

Drives the scan from a YAML/JSON config, keeping repeatable settings out of the command line.

python apileaks.py scan \
  --config config/production_api.yaml \
  --target https://api.example.com

Intermediate uses

Examples that tune discovery, evasion, resilience, and logging on top of the orchestrated run. These are the flags you'll reach for in a realistic assessment.

1. Framework detection and version fuzzing

Detects the backend framework and enumerates API versions during discovery, tuning the detection confidence and the version patterns searched.

python apileaks.py scan \
  --target https://api.example.com \
  --detect-framework \
  --fuzz-versions \
  --framework-confidence 0.8 \
  --version-patterns /v1,/v2,/api/v1

2. User-Agent rotation (WAF evasion)

Rotates the User-Agent to make detection harder. The three options (random, fixed, file) are mutually exclusive.

python apileaks.py scan \
  --target https://api.example.com \
  --user-agent-random

3. Seed extensions and per-request resilience

Expands wordlist entries with file extensions and hardens each discovery request with a timeout and retries.

python apileaks.py scan \
  --target https://api.example.com \
  -x json,php \
  --timeout 30 \
  --retries 5

4. Recursion control (depth, budget, concurrency)

Tunes how deep discovery recurses, the total request budget, and how many requests run in parallel.

python apileaks.py scan \
  --target https://api.example.com \
  --depth 5 \
  --max-requests 5000 \
  --concurrency 100

5. Recursion scope

Restricts which discovered endpoints recursion descends into, by status class and/or endpoint type. It only narrows the default eligibility, never relaxes it.

python apileaks.py scan \
  --target https://api.example.com \
  --recursion-status 2xx,3xx \
  --recursion-type admin,api_version

6. Route through an intercepting proxy

Sends all scan traffic through Burp/Caido/Hetty. TLS verification is auto-disabled while proxying; re-enable it with --proxy-verify-ssl after installing the proxy CA.

python apileaks.py scan \
  --target https://api.example.com \
  --modules bola,auth,ssrf \
  --proxy http://127.0.0.1:8080

7. Structured logging to a file

Emits JSON-formatted logs to a file at a chosen verbosity, useful for pipelines and later analysis.

python apileaks.py scan \
  --target https://api.example.com \
  --log-level INFO \
  --log-file full-scan.log \
  --json-logs

Advanced uses

Examples that exploit the scan's full capabilities: bundled advanced discovery features, non-destructive runs, SARIF and baseline-gated CI/CD integration, and automated JWT detection with real key material.

1. Enable all advanced discovery features

Turns on the full advanced discovery bundle in one flag and pairs it with User-Agent rotation.

python apileaks.py scan \
  --target https://api.example.com \
  --enable-advanced \
  --user-agent-random \
  --output advanced-security-scan

2. Toggle individual advanced features

Enables specific advanced capabilities — payload encoding/obfuscation, WAF detection/evasion, subdomain discovery, and CORS analysis — without the full bundle.

python apileaks.py scan \
  --target https://api.example.com \
  --enable-payload-encoding \
  --enable-waf-evasion \
  --enable-subdomain-discovery \
  --enable-cors-analysis

3. Non-destructive scan

Restricts the run to safe methods and skips state-changing probes (POST/PUT/PATCH/DELETE), suitable for shared or production-like environments.

python apileaks.py scan \
  --target https://api.example.com \
  --safe-mode \
  --modules bola,auth,security_misconfig

4. Generate a SARIF report

Emits a SARIF 2.1.0 report for code-scanning dashboards alongside the standard report.

python apileaks.py scan \
  --target https://api.example.com \
  --sarif \
  --output scan-results

5. CI/CD gate with SARIF

Enables CI mode with deterministic exit codes, fails the pipeline on high or critical findings, and emits a SARIF artifact.

python apileaks.py scan \
  --target https://api.example.com \
  --ci-mode \
  --fail-on high \
  --sarif

6. Baseline-gated CI/CD

Compares against a baseline report so only newly introduced findings drive the severity gate.

python apileaks.py scan \
  --target https://api.example.com \
  --ci-mode \
  --fail-on medium \
  --baseline reports/previous-scan.json

7. Full CI/CD: non-destructive, baseline-gated, with SARIF

Combines CI mode, safe methods, baseline gating, and a SARIF artifact into one pipeline-ready invocation.

python apileaks.py scan \
  --target https://api.example.com \
  --ci-mode \
  --fail-on high \
  --safe-mode \
  --sarif \
  --baseline reports/baseline.json

8. Automated JWT detection with key material

Feeds the auth module real key material so the algorithm-confusion and expired-token-acceptance checks run with a public key (or a JWKS URL) and a known signing secret.

python apileaks.py scan \
  --target https://api.example.com \
  --modules auth \
  --public-key ./idp_public.pem \
  --signing-secret 's3cr3t'

9. Deep discovery combined with a full orchestrated scan

Combines bounded deep recursion, extensions, resilience, and framework detection with the full module set for maximum coverage.

python apileaks.py scan \
  --target https://api.example.com \
  --detect-framework \
  --fuzz-versions \
  --depth 5 \
  --max-requests 8000 \
  --concurrency 100 \
  -x json,php \
  --timeout 30 \
  --retries 5 \
  --output deep-scan

OWASP Module Commands (owasp)

The owasp command group exposes each OWASP API Security Top 10 detection module as a first-class subcommand so you can run exactly one module in isolation (a red-team focus), rather than the full orchestrated scan.

  • apileaks owasp (no subcommand) prints one line per registered module — its key, OWASP category, and a one-line summary.
  • apileaks owasp <key> --target URL runs only that module against the target.

Each module subcommand accepts the shared transversal options; bola and auth additionally accept their own module-specific options (the other eight modules accept transversal options only).

Available modules

Key OWASP Summary
bola API1 Broken Object Level Authorization (BOLA) detection
auth API2 Broken Authentication detection
property API3 Broken Object Property Level Authorization detection
resource API4 Unrestricted Resource Consumption detection
function_auth API5 Broken Function Level Authorization detection
business_flow API6 Unrestricted Access to Sensitive Business Flows detection
ssrf API7 Server-Side Request Forgery (SSRF) detection
security_misconfig API8 Security Misconfiguration detection
inventory API9 Improper Inventory Management detection
unsafe_consumption API10 Unsafe Consumption of APIs detection

Syntax

# List every module (key, OWASP category, summary)
python apileaks.py owasp

# Run exactly one module in isolation
python apileaks.py owasp <key> --target URL [OPTIONS]

Examples

# List all available modules
python apileaks.py owasp

# Run only the BOLA module against a target
python apileaks.py owasp bola --target https://api.example.com

# Run only Broken Authentication detection with a JWT
python apileaks.py owasp auth \
  --target https://api.example.com \
  --jwt "eyJ0eXAiOiJKV1Q..."

# Run only the SSRF module
python apileaks.py owasp ssrf --target https://api.example.com

When to use which. Prefer scan for full-coverage assessments and CI gating (it runs discovery + all modules and drives --ci-mode/--fail-on/--sarif/--baseline/--safe-mode). Reach for owasp <key> when you want to focus on a single vulnerability class. Use scan --modules a,b when you want a subset of two or more modules aggregated in one report. A deprecated full --modules bola invocation maps directly to apileaks owasp bola.

JWT Utilities

APILeak includes comprehensive JWT security testing utilities organized as a command group.

JWT Command Group

All JWT utilities are accessed through the jwt command group:

python apileaks.py jwt [SUBCOMMAND] [OPTIONS]

This is a brief reference. For the full JWT attack methodology and deep-dive walkthroughs, see JWT Attacks.

Available Subcommands

Subcommand Purpose Description
decode Token Analysis Decode and analyze JWT tokens
encode Token Generation Create JWT tokens for testing
verify Signature Verification Verify a token's signature (HMAC secret or public key)
genkey Key Generation Generate an RSA or EC keypair for testing
jwks-to-key JWKS Conversion Convert a JWKS entry to a PEM public key
test-alg-none Algorithm Confusion Test alg:none vulnerability (signature stripping)
test-null-signature Null Signature Test null signature bypass (signature stripping)
test-alg-confusion Key Confusion Test RS256/ES256→HS256 substitution attack
brute-secret Secret Brute-force Crack weak HMAC secrets (bruteforcing HS256 key)
test-kid-injection Key ID Injection Test kid parameter injection
test-jwks-spoof JWKS Spoofing Test JWKS URL spoofing
test-inline-jwks Inline JWKS Test inline JWKS injection
attack-test Comprehensive Suite Run all attack vectors against a live endpoint

Live-Endpoint Testing Options

Every test-* subcommand (and attack-test) accepts the following options to validate an attack against a real endpoint:

Option Description Example
-u, --url Target URL to test the attack against --url https://api.example.com/protected
-H, --header Custom header (repeatable) -H "X-API-Key: key123"
-d, --data POST data for endpoint testing -d '{"action":"read"}'
--timeout Request timeout in seconds --timeout 30

JWT Decode (jwt decode)

Decode and analyze JWT tokens with security insights.

Syntax

python apileaks.py jwt decode TOKEN

Arguments

Argument Description Example
TOKEN JWT token to decode eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

Example

python apileaks.py jwt decode eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT Encode (jwt encode)

Create JWT tokens for testing purposes.

Syntax

python apileaks.py jwt encode PAYLOAD [OPTIONS]

Arguments

Argument Description Example
PAYLOAD JWT payload as JSON string '{"sub":"user123","role":"admin"}'

Options

Option Description Default Example
--header JWT header as JSON string {"alg":"HS256","typ":"JWT"} --header '{"alg":"HS512","typ":"JWT"}'
--secret Secret key for signing secret --secret mysecretkey

Examples

# Basic JWT encoding
python apileaks.py jwt encode '{"sub":"user123","role":"user"}'

# With custom secret
python apileaks.py jwt encode \
  '{"sub":"admin","role":"admin","exp":1735689600}' \
  --secret mysecretkey

# With custom header
python apileaks.py jwt encode \
  '{"sub":"user123"}' \
  --header '{"alg":"HS512","typ":"JWT"}' \
  --secret strongsecret

JWT Security Testing

APILeak provides advanced JWT security testing capabilities to identify common vulnerabilities.

Algorithm Confusion Attack (jwt test-alg-none)

Test if the server accepts unsigned tokens with alg:none.

python apileaks.py jwt test-alg-none TOKEN [--payload CUSTOM_PAYLOAD]

Examples:

# Basic alg:none test
python apileaks.py jwt test-alg-none eyJ0eXAiOiJKV1Q...

# Inject a custom admin payload
python apileaks.py jwt test-alg-none TOKEN --payload '{"sub":"admin","role":"admin"}'

# Validate the attack against a live endpoint
python apileaks.py jwt test-alg-none TOKEN --url https://api.example.com/admin

Null Signature Testing (jwt test-null-signature)

Test null/empty signature bypass techniques.

python apileaks.py jwt test-null-signature TOKEN [--payload CUSTOM_PAYLOAD]

Examples:

# Basic null signature test
python apileaks.py jwt test-null-signature TOKEN

# Inject a custom admin payload
python apileaks.py jwt test-null-signature TOKEN --payload '{"sub":"admin","admin":true}'

# Validate against a protected endpoint
python apileaks.py jwt test-null-signature TOKEN --url https://api.example.com/protected

Key Confusion / Substitution Attack (jwt test-alg-confusion)

Test the RS256/ES256 → HS256 key-confusion (Substitution) attack: forge a token signed with the target's public key used as an HMAC secret. Requires --public-key (a PEM/DER file path or inline PEM). One forged token is produced per public-key representation (PEM ±newline, DER, x5c).

python apileaks.py jwt test-alg-confusion TOKEN --public-key PATH_OR_PEM [--payload CUSTOM_PAYLOAD]
# Basic offline forgery from a public key file
python apileaks.py jwt test-alg-confusion TOKEN --public-key server_pub.pem

# Inline PEM material
python apileaks.py jwt test-alg-confusion TOKEN --public-key "$(cat server_pub.pem)"

# Escalate a claim while forging the confused token
python apileaks.py jwt test-alg-confusion TOKEN --public-key server_pub.pem --payload '{"role":"admin"}'

# Validate against a live endpoint
python apileaks.py jwt test-alg-confusion TOKEN --public-key server_pub.pem --url https://api.example.com/admin

HMAC Secret Brute-force (jwt brute-secret)

Attempt to crack weak HMAC secrets using wordlists, then forge a token.

python apileaks.py jwt brute-secret TOKEN [OPTIONS]

Options:

  • --wordlist, -w: Wordlist file (default: wordlists/jwt_secrets.txt)
  • --max-attempts: Maximum attempts (default: 1000)
  • -u/--url, -H/--header, -d/--data, --timeout: live-endpoint testing (see above)

Examples:

# Basic secret brute-force
python apileaks.py jwt brute-secret TOKEN

# Use a custom secrets wordlist
python apileaks.py jwt brute-secret TOKEN --wordlist custom_secrets.txt

# Crack the secret and test the forged token against a real endpoint
python apileaks.py jwt brute-secret TOKEN \
  --url https://api.example.com/admin \
  -H "X-API-Key: key123"

Key ID Injection (jwt test-kid-injection)

Test kid parameter injection (path traversal, arbitrary keys, remote key fetch).

python apileaks.py jwt test-kid-injection TOKEN [--kid-payload PAYLOAD] [--payload JSON]

Examples:

# Basic kid injection test
python apileaks.py jwt test-kid-injection TOKEN

# Path-traversal kid payload
python apileaks.py jwt test-kid-injection TOKEN --kid-payload "../../etc/passwd"

# Remote key fetch + custom payload against a live endpoint
python apileaks.py jwt test-kid-injection TOKEN \
  --kid-payload "http://attacker.com/key.pem" \
  --payload '{"admin":true}' \
  --url https://api.example.com/protected

JWKS Spoofing (jwt test-jwks-spoof)

Test JWKS URL (jku) spoofing vulnerabilities.

python apileaks.py jwt test-jwks-spoof TOKEN [--jwks-url URL]

Examples:

# Basic JWKS spoofing test
python apileaks.py jwt test-jwks-spoof TOKEN

# Custom malicious JWKS URL
python apileaks.py jwt test-jwks-spoof TOKEN --jwks-url http://attacker.com/jwks.json

# Validate against a live endpoint
python apileaks.py jwt test-jwks-spoof TOKEN \
  --jwks-url http://attacker.com/jwks.json \
  --url https://api.example.com/protected

Inline JWKS Injection (jwt test-inline-jwks)

Test inline JWKS injection (embed an attacker-controlled public key in the header).

python apileaks.py jwt test-inline-jwks TOKEN

Examples:

# Basic inline JWKS test
python apileaks.py jwt test-inline-jwks TOKEN

# Validate against a live endpoint with custom headers
python apileaks.py jwt test-inline-jwks TOKEN \
  --url https://api.example.com/admin \
  -H "X-API-Key: key123"

Comprehensive Attack Testing (jwt attack-test)

Run all attack vectors (algorithm confusion, secret attacks, injection, payload manipulation) against a live endpoint with baseline comparison and confidence scoring.

python apileaks.py jwt attack-test TOKEN --url URL [OPTIONS]

Examples:

# Full automated attack suite against a protected endpoint
python apileaks.py jwt attack-test TOKEN --url https://api.example.com/protected

# With custom headers
python apileaks.py jwt attack-test TOKEN \
  -u https://api.example.com/protected \
  -H "X-API-Key: key123"

# With POST data for the endpoint under test
python apileaks.py jwt attack-test TOKEN \
  -u https://api.example.com/protected \
  -d '{"action":"read"}'

JWT Security Testing Workflow

For comprehensive JWT security testing, use this workflow:

# 1. Decode and analyze the token
python apileaks.py jwt decode $TOKEN

# 2. Test algorithm confusion
python apileaks.py jwt test-alg-none $TOKEN

# 3. Test null signature bypass
python apileaks.py jwt test-null-signature $TOKEN

# 4. Attempt secret brute-force
python apileaks.py jwt brute-secret $TOKEN

# 5. Test kid injection
python apileaks.py jwt test-kid-injection $TOKEN

# 6. Test JWKS spoofing
python apileaks.py jwt test-jwks-spoof $TOKEN

# 7. Test inline JWKS
python apileaks.py jwt test-inline-jwks $TOKEN

# 8. Or run the full automated suite against a live endpoint in one shot
python apileaks.py jwt attack-test $TOKEN --url https://api.example.com/protected

Proxy Integration

APILeak can route all of its HTTP traffic (discovery, parameter/header fuzzing, OWASP testing, and the targeted follow-up scan) through an intercepting proxy so that every request and response can be captured, inspected, and replayed in tools like Burp Suite, Caido, or Hetty.

Flags

Option Description
--proxy URL Send all traffic through the proxy at URL (e.g. http://127.0.0.1:8080). Available on dir, par, and scan.
--proxy-verify-ssl Keep TLS certificate verification enabled while proxying.

TLS behavior

Intercepting proxies terminate TLS with their own certificate authority. To avoid certificate errors against HTTPS targets, TLS verification is automatically disabled when --proxy is set. After installing the proxy's CA certificate in your trust store, pass --proxy-verify-ssl to re-enable verification.

Default proxy endpoints

Tool Default proxy listener
Burp Suite http://127.0.0.1:8080
Caido http://127.0.0.1:8080
Hetty http://127.0.0.1:8080

Examples

# Directory discovery through Burp Suite
python apileaks.py dir \
  --target https://api.example.com \
  --proxy http://127.0.0.1:8080

# Authenticated discovery through a proxy (JWT + proxy together)
python apileaks.py dir \
  --target https://api.example.com \
  --jwt "eyJ0eXAiOiJKV1Q..." \
  --proxy http://127.0.0.1:8080

# Parameter fuzzing through Caido
python apileaks.py par \
  --target https://api.example.com/users/123 \
  --proxy http://127.0.0.1:8080

# Full OWASP scan through Hetty
python apileaks.py scan \
  --target https://api.example.com \
  --modules bola,auth,ssrf \
  --proxy http://127.0.0.1:8080

# Proxy with TLS verification kept on (after installing the proxy CA)
python apileaks.py scan \
  --target https://api.example.com \
  --proxy http://127.0.0.1:8080 \
  --proxy-verify-ssl

# Triage discovery through a proxy, saving a session for later replay
python apileaks.py dir \
  --target https://api.example.com \
  --proxy http://127.0.0.1:8080 \
  --status-code 2xx \
  --save-session session.json

Environment Variables

APILeak supports configuration through environment variables:

Variable Description Default CLI Equivalent
APILEAK_TARGET Target URL - --target
APILEAK_LOG_LEVEL Logging level INFO --log-level
APILEAK_RATE_LIMIT Requests per second 10 --rate-limit
APILEAK_MODULES OWASP modules All modules --modules
APILEAK_JWT_TOKEN JWT token - --jwt
APILEAK_USER_AGENT Custom User-Agent Default --user-agent-custom
APILEAK_TIMEOUT Request timeout 10 -
APILEAK_MAX_DEPTH Max recursion depth 3 -
APILEAK_VERIFY_SSL Verify SSL certificates true -
APILEAK_OUTPUT_DIR Output directory reports -

Example Usage

# Set environment variables
export APILEAK_TARGET="https://api.example.com"
export APILEAK_MODULES="bola,auth,property"
export APILEAK_JWT_TOKEN="eyJ0eXAiOiJKV1Q..."
export APILEAK_RATE_LIMIT="5"

# Run scan with environment variables
python apileaks.py scan

Exit Codes

APILeak uses specific exit codes to indicate scan results:

Exit Code Meaning Description
0 Success No critical or high severity findings
1 High Severity High severity vulnerabilities found
2 Critical Severity Critical vulnerabilities found
3 Scan Error Scan failed due to technical issues (CI mode only)

CI/CD Integration

In CI/CD mode (--ci-mode), exit codes are determined by the --fail-on setting. The default is now high (previously critical), so a run without an explicit --fail-on fails on high or critical findings:

# Default gate (high): a plain --ci-mode run fails on high or critical findings
python apileaks.py scan --target URL --ci-mode

# Fail only on critical findings (previous default; still available explicitly)
python apileaks.py scan --target URL --ci-mode --fail-on critical

# Fail on high or critical findings (the new default, stated explicitly)
python apileaks.py scan --target URL --ci-mode --fail-on high

# Fail on medium, high, or critical findings
python apileaks.py scan --target URL --ci-mode --fail-on medium

Examples

Basic Usage Examples

# Quick endpoint discovery
python apileaks.py dir --target https://api.example.com

# Parameter fuzzing with authentication
python apileaks.py par \
  --target https://api.example.com/users/123 \
  --jwt "eyJ0eXAiOiJKV1Q..."

# Full security scan
python apileaks.py scan \
  --target https://api.example.com \
  --modules bola,auth,property

Advanced Usage Examples

# WAF evasion with random user agents
python apileaks.py scan \
  --target https://api.example.com \
  --user-agent-random \
  --enable-waf-evasion \
  --rate-limit 3

# Framework detection and version fuzzing
python apileaks.py scan \
  --target https://api.example.com \
  --detect-framework \
  --fuzz-versions \
  --framework-confidence 0.8

# Comprehensive scan with all advanced features
python apileaks.py scan \
  --target https://api.example.com \
  --enable-advanced \
  --jwt "eyJ0eXAiOiJKV1Q..." \
  --output comprehensive-scan

CI/CD Integration Examples

# GitHub Actions - SARIF artifact for code scanning, baseline-gated
python apileaks.py scan \
  --target ${{ vars.API_TARGET_URL }} \
  --jwt ${{ secrets.API_JWT_TOKEN }} \
  --ci-mode \
  --fail-on critical \
  --sarif \
  --baseline reports/baseline.json \
  --output github-scan-${{ github.run_id }}

# GitLab CI - non-destructive scan that fails on high+ findings
python apileaks.py scan \
  --target $API_TARGET_URL \
  --jwt $API_JWT_TOKEN \
  --ci-mode \
  --fail-on high \
  --safe-mode \
  --sarif \
  --output gitlab-scan-$CI_PIPELINE_ID

# Jenkins
python apileaks.py scan \
  --target ${API_TARGET_URL} \
  --jwt ${API_JWT_TOKEN} \
  --ci-mode \
  --fail-on critical \
  --output jenkins-scan-${BUILD_ID}

# Non-blocking discovery triage in CI (publishes session + Markdown artifacts)
python apileaks.py dir \
  --target $API_TARGET_URL \
  --status-code 2xx \
  --save-session artifacts/session.json \
  --export md \
  --export-file artifacts/discovery.md \
  --interactive \
  --ci-mode

Configuration File Examples

# Using YAML configuration
python apileaks.py scan --config config/production_api.yaml

# Override config with CLI parameters
python apileaks.py scan \
  --config config/base_config.yaml \
  --target https://staging-api.example.com \
  --modules bola,auth

JWT Utility Examples

# Decode a JWT token
python apileaks.py jwt decode eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

# Create a test JWT token
python apileaks.py jwt encode \
  '{"sub":"testuser","role":"admin","exp":1735689600}' \
  --secret testsecret

# Create JWT with custom algorithm
python apileaks.py jwt encode \
  '{"sub":"user123"}' \
  --header '{"alg":"HS512","typ":"JWT"}' \
  --secret strongsecret

# Test JWT security vulnerabilities
python apileaks.py jwt test-alg-none TOKEN
python apileaks.py jwt brute-secret TOKEN --wordlist secrets.txt
python apileaks.py jwt test-kid-injection TOKEN

# Run the full automated JWT attack suite against a live endpoint
python apileaks.py jwt attack-test TOKEN --url https://api.example.com/protected

Output and Logging Examples

# Debug logging to file
python apileaks.py scan \
  --target https://api.example.com \
  --log-level DEBUG \
  --log-file debug-scan.log

# JSON structured logging
python apileaks.py scan \
  --target https://api.example.com \
  --json-logs \
  --log-file structured.log

# Custom output filename
python apileaks.py scan \
  --target https://api.example.com \
  --output my-security-audit-2024

For more detailed information, see:


Replay Command (replay)

Re-issue HTTP requests from a prior apileaks scan report (JSON).

apileaks replay REPORT [OPTIONS]

REPORT is the path to a .json report file generated by dir, par, or scan.

Options

Option Description Default
-l, --list List all replayable requests — no HTTP issued false
-u, --url TEXT Filter: only requests whose URL contains this substring
-m, --method TEXT Filter: only requests with this HTTP method (e.g. POST)
--source [endpoint|finding] Filter by source section
-i, --index N Replay only item N from the filtered list (0-based)
--all Replay ALL matching requests (default: first match only) false
--proxy URL Forward request through Burp/Caido/Hetty
--jwt TOKEN Inject Authorization: Bearer TOKEN
-H, --header Name: Value Additional request header (repeatable)
--timeout FLOAT Per-request timeout in seconds 30.0
--no-verify Disable TLS certificate verification false

Examples

# List all replayable requests
apileaks replay reports/scan.json --list

# Replay item 3 (0-based) through Burp Suite
apileaks replay reports/scan.json --index 3 --proxy http://127.0.0.1:8080

# Replay all POST findings with a JWT
apileaks replay reports/scan.json --source finding --method POST --jwt eyJ... --all

# Replay every endpoint containing '/admin'
apileaks replay reports/scan.json --url /admin --all

Wordlist Management (wordlist)

Download, cache, and list Assetnote public wordlists.

Wordlists are cached in ~/.cache/apileaks/wordlists/ and can be used directly in --wordlist via the assetnote: prefix.

Subcommands

wordlist list

List available Assetnote wordlists (fetches catalogue on first run, cached 24 h).

apileaks wordlist list
apileaks wordlist list --filter apiroutes
apileaks wordlist list --limit 20 --refresh
Option Description Default
-f, --filter TERM Filter by name/alias substring
--refresh Force re-fetch of the catalogue false
--limit N Maximum entries to display (0 = unlimited) 50

wordlist fetch

Download and cache a wordlist by alias or filename.

apileaks wordlist fetch apiroutes-210328
apileaks wordlist fetch raft-large-words --refresh

wordlist cache

Show the local cache directory and its contents.

apileaks wordlist cache

Using Assetnote wordlists in scans

Pass the assetnote: prefix to --wordlist in dir or par. The wordlist is auto-downloaded and cached on first use. Append :N to use only the first N lines.

# Auto-download and use the first 20 000 lines of apiroutes-210328
apileaks dir --target https://api.example.com \
             --wordlist assetnote:apiroutes-210328:20000

# Use the full apiroutes wordlist
apileaks dir --target https://api.example.com \
             --wordlist assetnote:apiroutes-210328

Multi-Target Scanning (--target-file, --max-hosts)

All three primary commands (dir, par, scan) and all owasp subcommands accept a file of targets in place of (or alongside) --target.

Option Description Commands
--target-file FILE Plain-text file, one URL per line (# comments and blank lines skipped). Lines without a scheme are auto-prefixed with https:// dir, par, scan, all owasp subcommands
--max-hosts N Scan only the first N hosts from the file same
# Scan 50 API hosts from a file
apileaks dir --target-file hosts.txt --max-hosts 50

# Combine explicit target + file (explicit target becomes first)
apileaks scan --target https://api.primary.com --target-file others.txt

# Multi-target parameter fuzzing
apileaks par --target-file endpoints.txt --wordlist params.txt

Hosts are scanned sequentially. A per-host summary table is printed at the end.


Spec-Aware Discovery

When --openapi or --postman is supplied to dir, APILeaks loads the full operation schema and sends contextually correct requests for each route.

Option Description
--openapi PATH OpenAPI/Swagger document (JSON or YAML). Repeatable.
--postman PATH Postman collection (JSON). Repeatable.
--spec-methods-only Probe spec-seeded paths with only the method declared in the spec. Paths from the wordlist continue using --methods as usual.
# Send per-route query params, headers, and body from spec
apileaks dir --target https://api.example.com --openapi api.yaml

# Strict method matching: only GET where spec says GET, only POST where spec says POST
apileaks dir --target https://api.example.com --openapi api.yaml --spec-methods-only

Wildcard Quarantine (--quarantine-threshold)

Halt discovery early if a host responds positively (non-404) to every path, which typically indicates a wildcard / catch-all configuration.

Option Description Default
--quarantine-threshold N Stop after N consecutive non-404 responses. 0 disables. 0 (disabled)
# Stop discovery if 10 consecutive hits are returned
apileaks dir --target https://api.example.com --quarantine-threshold 10

This complements the existing soft-404 baseline detection, which runs before discovery starts. Quarantine catches wildcard hosts that slip through the initial probes by detecting the pattern during live scanning.