{"id":13845969,"url":"https://github.com/ethicalhackingplayground/pathbuster","last_synced_at":"2026-01-22T04:01:23.354Z","repository":{"id":93643661,"uuid":"607995691","full_name":"ethicalhackingplayground/pathbuster","owner":"ethicalhackingplayground","description":"A path-normalization pentesting tool.","archived":false,"fork":false,"pushed_at":"2023-09-25T14:24:02.000Z","size":7092,"stargazers_count":129,"open_issues_count":2,"forks_count":14,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-07T10:33:01.387Z","etag":null,"topics":["bug-bounty","path-normalization","rust","url-filter-bypass"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ethicalhackingplayground.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-03-01T05:06:18.000Z","updated_at":"2025-08-08T20:22:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"4365fe16-cd60-4f81-8691-4f5512c644da","html_url":"https://github.com/ethicalhackingplayground/pathbuster","commit_stats":{"total_commits":103,"total_committers":2,"mean_commits":51.5,"dds":0.01941747572815533,"last_synced_commit":"e1a7ed04f23bf3d805d01b7ffe7acfee6572b087"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/ethicalhackingplayground/pathbuster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethicalhackingplayground%2Fpathbuster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethicalhackingplayground%2Fpathbuster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethicalhackingplayground%2Fpathbuster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethicalhackingplayground%2Fpathbuster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethicalhackingplayground","download_url":"https://codeload.github.com/ethicalhackingplayground/pathbuster/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethicalhackingplayground%2Fpathbuster/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28653625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bug-bounty","path-normalization","rust","url-filter-bypass"],"created_at":"2024-08-04T17:04:14.222Z","updated_at":"2026-01-22T04:01:23.347Z","avatar_url":"https://github.com/ethicalhackingplayground.png","language":"Rust","funding_links":["https://buymeacoffee.com/z0idsec"],"categories":["Rust"],"sub_categories":[],"readme":"\r\n\u003ch1 align=\"center\"\u003epathbuster\r\n  \u003cbr\u003e\r\n\u003c/h1\u003e\r\n\r\n\u003ch4 align=\"center\"\u003eA path-normalization pentesting tool (inspired by \u003ca href=\"https://github.com/ffuf/ffuf\"\u003eFFUF\u003c/a\u003e)\u003c/h4\u003e\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003ca href=\"/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\"/\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://www.rust-lang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Made%20with-Rust-1f425f.svg\"/\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://github.com/ethicalhackingplayground/pathmbuster/issues\"\u003e\u003cimg src=\"https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat\"\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://twitter.com/z0idsec\"\u003e\u003cimg src=\"https://img.shields.io/twitter/follow/z0idsec.svg?logo=twitter\"\u003e\u003c/a\u003e\r\n  \u003cbr\u003e\r\n\u003c/p\u003e\r\n\r\n---\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003ca href=\"#whats-new\"\u003eWhats New\u003c/a\u003e •\r\n  \u003ca href=\"#bug-fixes\"\u003eBug Fixes\u003c/a\u003e •\r\n  \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e •\r\n  \u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e •\r\n  \u003ca href=\"#example-scan\"\u003eExample Scan\u003c/a\u003e •\r\n  \u003ca href=\"#examples\"\u003eExamples\u003c/a\u003e •\r\n  \u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e •\r\n  \u003ca href=\"#license\"\u003eLicense\u003c/a\u003e •\r\n\u003c/p\u003e\r\n\r\n---\r\n\r\n## What's New?\r\n\r\n- [x] Unified response filtering under **--filter-\\*** flags with stage prefixes (V/F).\r\n- [x] Implemented **--drop-after-fail** which will ignore requests with the same response code multiple times in a row.\r\n- [x] Added in a **--proxy** argument, so you can now perform proxy-related tasks such as sending everything to burp.\r\n- [x] Pathbuster will now give you an eta on when the tool will finish processing all jobs.\r\n- [x] Added in a **--skip-brute** argument, so you have the choice to perform a directory brute force or not.\r\n- [x] Split scan matching into **--validate-status** and **--fingerprint-status** for scan-stage control.\r\n- [x] Added in a **--skip-validation** argument which is used to bypass known protected endpoints using traversals.\r\n- [x] Added in a **--header** argument which is used to add in additonal headers into each request.\r\n- [x] Added **--methods** for scanning with one or more HTTP methods (comma-separated).\r\n- [x] Added **--path** for scanning a single path without a wordlist.\r\n- [x] Added wordlist transforms via **--wordlist-manipulation** (alias: **--wm**).\r\n- [x] Added traversal strategy selection via **--traversal-strategy** (`greedy` / `quick`).\r\n- [x] Added bruteforce gating via **--wordlist-status** and output filtering via **--disable-show-all**.\r\n- [x] Added bruteforce batching via **--brute-queue-concurrency** and optional noise filtering via **--ac**.\r\n---\r\n\r\n\r\n## Installation\r\n\r\nInstall rust\r\n\r\n```bash\r\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\r\n```\r\n\r\nInstall pathbuster\r\n\r\n```bash\r\ncargo install pathbuster\r\n```\r\n\r\n\r\n## Usage\r\n\r\n```bash\r\npathbuster -h\r\n```\r\n\r\nThis command will show the tool's help information and present a list of all the switches that are available.\r\n\r\n### Default config\r\n\r\nOn first run, Pathbuster will create a default config file at:\r\n\r\n- Linux/macOS: `~/.pathbuster/config.yml`\r\n- Windows: `%USERPROFILE%\\\\.pathbuster\\\\config.yml`\r\n\r\nThe generated config contains the default settings, with optional keys commented out.\r\n\r\nYou can also explicitly point to a config file:\r\n\r\n```bash\r\npathbuster --config ./config.yml\r\n```\r\n\r\n### Common options (high level)\r\n\r\n- Targets: `--url \u003cURL\u003e` (repeatable) or `--input-file \u003cFILE\u003e`\r\n- Payloads: `--payloads \u003cFILE\u003e`\r\n- Raw request: `--raw-request \u003cFILE\u003e` (optional, uses `*` as injection points)\r\n- Bruteforce target: `--wordlist \u003cFILE\u003e` (recommended) or `--path \u003cPATH\u003e` and optional `--wordlist-dir \u003cDIR\u003e`\r\n- Wordlist manipulation (optional): `--wordlist-manipulation \u003cLIST\u003e` (alias: `--wm`)\r\n- Output: `--output \u003cFILE\u003e` and optional `--output-format \u003ctext|json|xml|html\u003e`\r\n- Output filtering: `--disable-show-all` (only show matches allowed by `--wordlist-status`)\r\n- Networking: `--proxy \u003cURL\u003e`, `--follow-redirects`, `--timeout \u003cSECONDS\u003e`, `--methods \u003cMETHODS\u003e`\r\n- Validation tuning: `--response-diff-threshold \u003cMIN-MAX\u003e`\r\n- Bruteforce tuning: `--wordlist-status \u003cCODES\u003e`, `--brute-queue-concurrency \u003cN\u003e`, `--ac`\r\n- Filters:\r\n  - `--filter-status \u003cSET\u003e` (e.g. `V:404,F:500` or `404,500` for both stages)\r\n  - `--filter-size \u003cSET\u003e` (e.g. `V:1234,F:5678`)\r\n  - `--filter-words \u003cSET\u003e` (e.g. `V:10,F:25`)\r\n  - `--filter-lines \u003cSET\u003e` (e.g. `V:5,F:20`)\r\n  - `--filter-regex \u003cSTAGE:REGEX\u003e` (repeatable, e.g. `--filter-regex V:\u003cre\u003e --filter-regex F:\u003cre\u003e`)\r\n  - Stage-scoped filters and status matchers work with both traversal strategies (`greedy` and `quick`)\r\n\r\n## Traversal strategies (quick vs greedy)\r\n\r\nPathbuster has two traversal strategies you can select via `--traversal-strategy`:\r\n\r\n### Greedy (default)\r\n\r\n- Probes depths from `--start-depth` up to `--max-depth` to find a depth where `--fingerprint-status` matches.\r\n- Once a “fingerprint depth” is found, it validates every depth back down toward `--start-depth`.\r\n- Higher request count, but more consistent when you don’t know how the target normalizes paths.\r\n\r\n### Quick\r\n\r\n- Computes the “fingerprint depth” directly from the target URL path segment count plus `--start-depth` (clamped to `--max-depth`).\r\n- Validates a minimal set of depths (favoring speed over coverage) and moves on.\r\n- Lower request count, best when your base URL has meaningful path segments (e.g. `https://example.com/app/`).\r\n\r\n## Arguments\r\n\r\n| Flag | Value | Description |\r\n| --- | --- | --- |\r\n| `-u, --url` | `URL` (repeatable) | Target URL(s) to scan. |\r\n| `-i, --input-file` | `FILE` | Load target URLs from a file (one per line). |\r\n| `-C, --config` | `FILE` | Config file path (defaults to `~/.pathbuster/config.yml`). |\r\n| `--payloads` | `FILE` | Payload file path (one payload per line). |\r\n| `--raw-request` | `FILE` | Raw HTTP request template with `*` injection points. |\r\n| `--wordlist` | `FILE` | Wordlist file path (one word per line). |\r\n| `--path` | `PATH` | Scan a single path instead of using a wordlist. |\r\n| `--wordlist-dir` | `DIR` | Targeted wordlist directory (auto-selected by tech fingerprint). |\r\n| `--wordlist-manipulation, --wm` | `LIST` | Comma-separated wordlist transforms (see Wordlist manipulation). |\r\n| `--skip-brute` | (flag) | Skip bruteforce/discovery phase. |\r\n| `-s, --skip-validation` | (flag) | Skip validation phase and go straight to bruteforce/discovery. |\r\n| `-r, --rate` | `RPS` | Request rate limit (requests per second). |\r\n| `-t, --concurrency` | `N` | Max in-flight requests during scanning. |\r\n| `-w, --workers` | `N` | Number of runtime worker threads. |\r\n| `--timeout` | `SECONDS` | Per-request timeout. |\r\n| `-p, --proxy` | `URL` | HTTP proxy URL (e.g. `http://127.0.0.1:8080`). |\r\n| `--follow-redirects` | (flag) | Follow HTTP redirects. |\r\n| `--header` | `HEADER` | Add a header to all requests (`Key: Value`). |\r\n| `-m, --methods` | `METHODS` | Comma-separated HTTP methods to use (e.g. `GET,POST`). |\r\n| `--wordlist-status, --ws` | `CODES` | Allowed status codes for bruteforce findings (comma-separated). |\r\n| `--brute-queue-concurrency, --bqc, --bfc` | `N` | Max base URLs per bruteforce batch (0 = no batching). |\r\n| `--ac` | (flag) | Enable automatic collaboration filtering during bruteforce. |\r\n| `--drop-after-fail` | `CODES` | Stop scanning a target after these status codes (comma-separated). |\r\n| `--validate-status, --vs` | `CODES` | HTTP status matcher for validation phase. |\r\n| `--fingerprint-status` | `CODES` | HTTP status matcher for fingerprinting phase. |\r\n| `--filter-status` | `SET` | Exclude responses by HTTP status using stage prefixes (e.g. `V:404,F:500`). |\r\n| `--filter-size` | `SET` | Exclude responses by body size using stage prefixes (e.g. `V:1234,F:5678`). |\r\n| `--filter-words` | `SET` | Exclude responses by word count using stage prefixes (e.g. `V:10,F:25`). |\r\n| `--filter-lines` | `SET` | Exclude responses by line count using stage prefixes (e.g. `V:5,F:20`). |\r\n| `--filter-regex` | `STAGE:REGEX` | Exclude responses matching regex using stage prefixes (repeatable). |\r\n| `-d, --response-diff-threshold, --rdt` | `MIN-MAX` | Response diff threshold range for comparisons. |\r\n| `-I, --ignore-trailing-slash, --its` | (flag) | Treat URLs with/without trailing slash as equivalent. |\r\n| `--start-depth` | `N` | Initial traversal depth (0-based). |\r\n| `--max-depth` | `N` | Maximum traversal depth. |\r\n| `-X, --traversal-strategy, --ts` | `STRATEGY` | Traversal strategy (`greedy` or `quick`). |\r\n| `--disable-fingerprinting` | (flag) | Disable fingerprinting (WAF/tech). |\r\n| `--waf-test` | `NAME` | Only test for a specific WAF signature by name. |\r\n| `--tech` | `NAME` | Override detected tech name for targeted wordlist selection. |\r\n| `--disable-waf-bypass` | (flag) | Disable WAF-aware payload transformations. |\r\n| `--bypass-level` | `N` | Bypass aggressiveness level (0-3). |\r\n| `--bypass-transform` | `NAME` (repeatable) | Force specific payload transform families. |\r\n| `-o, --output` | `FILE` | Write results to a file. |\r\n| `--output-format` | `FORMAT` | Output format (e.g. `text`, `json`). |\r\n| `-v, --verbose` | (count) | Increase verbosity (`-v`, `-vv`). |\r\n| `-c, --color` | (flag) | Enable colored output (overrides `--no-color`). |\r\n| `--disable-show-all, --dsa` | (flag) | Only show findings matching `--wordlist-status`. |\r\n| `--no-color` | (flag) | Disable colored output. |\r\n| `-h, --help` | (flag) | Print help. |\r\n| `-V, --version` | (flag) | Print version. |\r\n\r\n## Wordlist manipulation\r\n\r\n`--wordlist-manipulation \u003cLIST\u003e` (alias: `--wm`) applies one or more transforms to the bruteforce wordlist before scanning.\r\n\r\n`LIST` is a comma-separated list of transforms:\r\n\r\n- `sort`: Sort words (also enables `unique` via `dedup` when both are set)\r\n- `unique` / `uniq`: Deduplicate words (preserves first-seen order unless `sort` is also set)\r\n- `reverse` / `rev`: Reverse each word\r\n- `lower`: Lowercase each word\r\n- `upper`: Uppercase each word\r\n- `title`: Title-case each word (ASCII)\r\n- `prefix=\u003cSTR\u003e`: Prefix each word with `\u003cSTR\u003e`\r\n- `suffix=\u003cSTR\u003e`: Suffix each word with `\u003cSTR\u003e`\r\n- `replace=\u003cFROM:TO\u003e`: Replace substring `\u003cFROM\u003e` with `\u003cTO\u003e` (repeatable by adding multiple `replace=...` entries)\r\n- `smart`: Split naming conventions into separate words (`AdminPanel` -\u003e `Admin`, `Panel`; `admin_panel` -\u003e `admin`, `panel`; `admin-panel` -\u003e `admin`, `panel`)\r\n- `smartjoin=\u003cCASE:SEP\u003e`: Split then join with `SEP` (CASE is one of `c,l,u,t` or empty). Example: `smartjoin=l:_` turns `AdminPanel` into `admin_panel`.\r\n\r\nExamples:\r\n\r\n```bash\r\npathbuster \\\r\n  --url https://example.com/app/ \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt \\\r\n  --wordlist-manipulation sort,unique,lower,replace=..%2f:../\r\n```\r\n\r\n```bash\r\npathbuster \\\r\n  --url https://example.com/app/ \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt \\\r\n  --wm smartjoin=l:_\r\n```\r\n\r\n## Examples\r\n\r\nBasic usage (single target):\r\n\r\n```bash\r\npathbuster --url https://example.com/app/ \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt \\\r\n  --output ./output.html --output-format html\r\n```\r\n\r\n### Scan with multiple HTTP methods\r\n\r\n```bash\r\npathbuster --url https://example.com/app/ \\\r\n  --methods GET,POST \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt \\\r\n  --skip-brute\r\n```\r\n\r\n### Scan a single path (no wordlist)\r\n\r\n```bash\r\npathbuster --url https://example.com/app/ \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --path admin \\\r\n  --skip-brute\r\n```\r\n\r\n### Run a scan with explicit scan settings\r\n\r\n```bash\r\npathbuster \\\r\n  --url https://example.com/app/ \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt \\\r\n  --wordlist-dir ./wordlists/targeted \\\r\n  --rate 500 \\\r\n  --concurrency 200 \\\r\n  --timeout 10 \\\r\n  --response-diff-threshold 5-1000 \\\r\n  --validate-status 404 \\\r\n  --fingerprint-status 400,500 \\\r\n  --filter-status V:301,302,F:404 \\\r\n  --bypass-level 2 \\\r\n  --follow-redirects\r\n```\r\n\r\n### Use a raw HTTP request template with injection points\r\n\r\nCreate a request file containing one or more `*` markers:\r\n\r\n```http\r\nGET /app/* HTTP/1.1\r\nHost: example.com\r\nUser-Agent: pathbuster\r\nAccept: */*\r\n\r\n```\r\n\r\nThen run:\r\n\r\n```bash\r\npathbuster \\\r\n  --url https://example.com/app/ \\\r\n  --raw-request ./request.txt \\\r\n  --payloads ./payloads/traversals.txt \\\r\n  --wordlist ./wordlists/wordlist.txt\r\n```\r\n\r\n### Specify scan settings via config file\r\n\r\nCreate or edit `~/.pathbuster/config.yml`:\r\n\r\n```yaml\r\nrate: 500\r\nconcurrency: 200\r\ntimeout: 10\r\n\r\npayloads: ./payloads/traversals.txt\r\nwordlist: ./wordlists/wordlist.txt\r\n# Or scan a single path without a wordlist:\r\n# path: admin\r\nwordlist_dir: ./wordlists/targeted\r\nwordlist_manipulation: \"sort,unique,lower\"\r\nwordlist_status: \"200\"\r\ndisable_show_all: false\r\n\r\nvalidate_status: \"404\"\r\nfingerprint_status: \"400,500\"\r\nresponse_diff_threshold: \"5-1000\"\r\nfilter_status: \"\"\r\nfilter_size: \"\"\r\nfilter_words: \"\"\r\nfilter_lines: \"\"\r\nfilter_regex: []\r\n\r\nfollow_redirects: true\r\ndisable_fingerprinting: false\r\ndisable_waf_bypass: false\r\nbypass_level: 3\r\nbypass_transform: []\r\n```\r\n\r\nRun using that config:\r\n\r\n```bash\r\npathbuster --url https://example.com/app/ --config ~/.pathbuster/config.yml\r\n```\r\n\r\n---\r\n\r\n## Example scan:\r\n```bash\r\npathbuster --url https://example.com/app/ \\\r\n  --path internal/admin \\\r\n  --validate-status 404 \\\r\n  --fingerprint-status 404 \\\r\n  --traversal-strategy quick \\\r\n  --max-depth 5 \\\r\n  --rate 50 \\\r\n  --concurrency 20 \\\r\n  --timeout 5 \\\r\n  --wordlist-status 200 \\\r\n  --brute-queue-concurrency 3 \\\r\n  --disable-show-all\r\n```\r\n\r\n![Demo](static/demo.gif)\r\n\r\n---\r\n\r\n### Using as a Rust library\r\n\r\nLibrary usage examples are in the [examples](./examples) folder.\r\n\r\n- Basic runner example: [library_scan.rs](./examples/library_scan.rs)\r\n- Inline payloads + raw request example: [library_scan_inline.rs](./examples/library_scan_inline.rs)\r\n- Filters example: [library_scan_filters.rs](./examples/library_scan_filters.rs)\r\n- Skip-validation + wordlist manipulation example: [library_scan_skip_validation.rs](./examples/library_scan_skip_validation.rs)\r\n\r\nRun the example binary:\r\n\r\n```bash\r\ncargo run --example library_scan\r\n```\r\n\r\nYou can also run scans by constructing a `Runner` with `Options` and calling `run()`.\r\n\r\nBasic example (same as [library_scan.rs](./examples/library_scan.rs)):\r\n\r\n```rust\r\nuse std::error::Error;\r\n\r\nuse pathbuster::runner::{Options, PayloadSource, Runner};\r\n\r\n#[tokio::main]\r\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\r\n    let runner = Runner::new(Options {\r\n        urls: vec![\"https://example.com/app/\".to_string()],\r\n        payloads: PayloadSource::FilePath(\"./payloads/traversals.txt\".to_string()),\r\n        skip_brute: true,\r\n        rate: 10,\r\n        concurrency: 10,\r\n        timeout_seconds: 5,\r\n        max_depth: 2,\r\n        ..Options::default()\r\n    })?;\r\n\r\n    let result = runner.run().await?;\r\n\r\n    println!(\"Targets: {}\", result.fingerprints.len());\r\n    println!(\"Matches: {}\", result.matches.len());\r\n    for m in result.matches.iter() {\r\n        println!(\"{} {} {}\", m.base_url, m.status, m.result_url);\r\n    }\r\n\r\n    Ok(())\r\n}\r\n```\r\n\r\n---\r\n\r\n### Warning\r\n\r\nDo not run automated scans, brute forcing, or high-rate tooling (including Pathbuster) against PentesterLab infrastructure or any training platform you do not own or explicitly have permission to test.\r\n\r\n## Support Development\r\n\r\nIf this project helps you uncover any interesting or impactful bugs, I'd really appreciate a bit of support or recognition. A shout-out on Twitter/X ([@z0idsec](https://x.com/z0idsec)) or buying me a coffee goes a long way in supporting continued development and research.\r\n\r\n[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge\\\u0026logo=buy-me-a-coffee\\\u0026logoColor=black)](https://buymeacoffee.com/z0idsec)\r\n\r\nThanks for checking it out - hope you enjoy using it.\r\n\r\n\r\n## Contributing\r\n\r\nContributions are welcome and appreciated. If you're planning a significant change, please open an issue first to discuss the proposed approach and ensure alignment before submitting a pull request.\r\n\r\nWhen submitting changes, please ensure that any relevant tests are updated or added as appropriate.\r\n\r\n## Contributors\r\n\r\nThanks to everyone who has contributed to this project.\r\n\r\n\u003ca href=\"https://github.com/ethicalhackingplayground/pathbuster/graphs/contributors\"\u003e \u003cimg src=\"https://contrib.rocks/image?repo=ethicalhackingplayground/pathbuster\" /\u003e \u003c/a\u003e\r\n\r\n\r\n## License\r\n\r\nPathbuster is distributed under [MIT License](https://github.com/ethicalhackingplayground/pathbuster/blob/main/LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethicalhackingplayground%2Fpathbuster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethicalhackingplayground%2Fpathbuster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethicalhackingplayground%2Fpathbuster/lists"}