{"id":51636885,"url":"https://github.com/r0x4r/goswagger","last_synced_at":"2026-07-13T15:02:47.747Z","repository":{"id":361695639,"uuid":"1255235826","full_name":"R0X4R/goswagger","owner":"R0X4R","description":"goswagger is a minimal SwaggerHub OSINT scanner written in Go. It searches SwaggerHub APIs for a query, fetches discovered target URLs, and matches each fetched body against regex patterns from regex.yaml.","archived":false,"fork":false,"pushed_at":"2026-06-23T20:58:30.000Z","size":385,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-04T19:08:32.438Z","etag":null,"topics":["api","api-security","apisecurity","bug-bounty","bugbounty","bugbounty-tool","golang","osint","osint-tool","penetration-testing","rewrite","swagger","swaggerhub","swaggerspy"],"latest_commit_sha":null,"homepage":"","language":"Go","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/R0X4R.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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-31T15:23:09.000Z","updated_at":"2026-06-23T20:58:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/R0X4R/goswagger","commit_stats":null,"previous_names":["r0x4r/goswagger"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/R0X4R/goswagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/R0X4R%2Fgoswagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/R0X4R%2Fgoswagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/R0X4R%2Fgoswagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/R0X4R%2Fgoswagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/R0X4R","download_url":"https://codeload.github.com/R0X4R/goswagger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/R0X4R%2Fgoswagger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35426086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"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":["api","api-security","apisecurity","bug-bounty","bugbounty","bugbounty-tool","golang","osint","osint-tool","penetration-testing","rewrite","swagger","swaggerhub","swaggerspy"],"created_at":"2026-07-13T15:02:46.755Z","updated_at":"2026-07-13T15:02:47.741Z","avatar_url":"https://github.com/R0X4R.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![goswagger](https://github.com/R0X4R/goswagger/blob/main/.github/image.png?raw=true)\n\n**GOSWAGGER** is a minimal [**SwaggerHub**](https://swagger.io/) **OSINT scanner** written in Go.\nIt searches SwaggerHub APIs for a query, fetches **discovered target URLs**, and matches each **fetched body against regex patterns** from `regex.yaml`.\n\n## Background\n\nThis project is a Go rewrite created to improve my Go coding skills, and it is totally inspired by the original Python [**SwaggerSpy**](https://github.com/UndeadSec/SwaggerSpy) project.\n\n### Overview\n\nThe goal is to make SwaggerHub reconnaissance fast and repeatable for security researchers, developers, and IT teams by combining:\n\n- API discovery from SwaggerHub search results\n- configurable regex-based inspection\n- minimal, scan-friendly output\n\n### Swagger And OpenAPI\n\nSwagger (OpenAPI tooling) is a standard ecosystem for describing REST APIs in JSON or YAML, generating documentation, and improving API integration workflows.\n\n### SwaggerHub Context\n\nSwaggerHub is a collaborative API platform built around Swagger/OpenAPI where teams design, version, and publish API definitions.\n\n### Why OSINT Matters\n\nPublic API responses can accidentally include sensitive values. OSINT scanning helps reduce this risk by:\n\n1. Catching developer oversights early\n2. Supporting secure-by-default development habits\n3. Reducing chances of credential and token leaks\n4. Helping risk and exposure triage\n5. Supporting compliance and privacy reviews\n6. Creating practical feedback loops for engineering teams\n\n### Detection Workflow\n\n**GOSWAGGER** queries SwaggerHub, collects discovered target URLs, downloads each response, and applies regex patterns to detect potential secrets and credentials.\n\n## Install\n\n```bash\ngo install github.com/R0X4R/goswagger@latest\n```\n\nAfter the first run, `goswagger` automatically seeds the default regex file at:\n\n```bash\n~/.config/goswagger/regex.yaml\n```\n\nIf the file already exists, goswagger preserves your existing custom regex entries while automatically merging any missing default patterns from newer releases. The regex file may be rewritten when new default patterns are added so the local configuration stays up to date without removing user customizations.\n\n**Install from source**\n\n```bash\ngit clone https://github.com/R0X4R/goswagger.git \u0026\u0026 cd goswagger \u0026\u0026 go install .\n```\n\n## Usage\n\n```bash\ngoswagger [flags]\n```\n\nExample:\n\n```bash\ngoswagger -q example.com -t 25\n```\n\nFlags:\n\n| Short Flag | Long Flag    | Description                                                            |\n|------------|--------------|------------------------------------------------------------------------|\n| -q       | **--query**    | Search query required by SwaggerHub.                                   |\n| -r       | **--regex-file** | Path to the regex YAML file. Defaults to `~/.config/goswagger/regex.yaml`. |\n| -t       | **--threads**  | Worker count for fetching and matching. Defaults to `25`.              |\n| -m       | **--max-pages** | Maximum SwaggerHub pages to fetch. `0` means all pages.                |\n| -b       | **--base-url** | Override the SwaggerHub search URL format.                             |\n| -o       | **--output**   | Append matches to a text file while still printing to stdout.          |\n| -n       | **--no-color** | Disable colored terminal output.                                     |\n\n## Output\n\nMatches are printed in a compact bracketed format:\n\n```text\n[HIGH] https://example.com/swagger.json [GITHUB PERSONAL ACCESS TOKEN] [ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]\n```\n\n## Regex File Format\n\n`regex.yaml` uses a structured pattern format with metadata support.\n\nEach pattern entry contains:\n\n* `regex` → the detection regex\n* `description` → human-readable description\n* optional `confidence` → severity or confidence level\n\nExample:\n\n```yaml\npatterns:\n\n  github_personal_access_token:\n    regex: 'ghp_[a-zA-Z0-9]{36}'\n    description: GitHub Personal Access Token\n    confidence: high\n\n  stripe_live_secret_key:\n    regex: 'sk_live_[0-9a-zA-Z]{24}'\n    description: Stripe Live Secret Key\n    confidence: high\n\n  generic_api_key:\n    regex: '(?i)(api[_\\-]?key|apikey)[\\s]*[:=][\\s]*[a-zA-Z0-9_\\-]{16,64}'\n    description: Generic API Key\n    confidence: medium\n```\n\n## Pattern Fields\n\n| Field         | Required | Description                                    |\n| ------------- | -------- | ---------------------------------------------- |\n| `regex`       | Yes      | Go-compatible regular expression               |\n| `description` | Yes      | Human-readable detection label                 |\n| `confidence`  | No       | Detection confidence (`low`, `medium`, `high`) |\n\n## Adding New Regex Patterns\n\n1. Open `regex.yaml`\n2. Add a new entry under `patterns:`\n3. Provide a regex and description\n4. Run a scan to validate the pattern\n\n**Example:**\n\n```yaml\npatterns:\n\n  my_custom_token:\n    regex: 'token_[A-Za-z0-9]{24}'\n    description: Custom Internal Token\n    confidence: medium\n```\n\n**Output structure:**\n\n```text\n[CONFIDENCE] URL [PATTERN NAME] [MATCH]\n```\n\n## Notes About Regex Compatibility\n\n* Regexes use Go's `regexp` engine\n* Invalid regex entries are skipped automatically\n* YAML strings should usually use single quotes `'....'`\n* Escape backslashes properly when needed\n\n**Example:**\n\n```yaml\nregex: 'sk_live_[0-9a-zA-Z]{24}'\n```\n\n**Not:**\n\n```yaml\nregex: \"sk_live_[0-9a-zA-Z]{24}\"\n```\n\nunless escaping is required.\n\n## Recommended Confidence Levels\n\n| Confidence | Meaning                                       |\n| ---------- | --------------------------------------------- |\n| `high`     | Very likely to be a real credential or secret |\n| `medium`   | Possible secret, may generate false positives |\n| `low`      | Informational or noisy detections             |\n\n\n## Examples\n\nRun a scan and print to the terminal:\n\n```bash\ngoswagger -q admin -t 5\n```\n\nRun a scan and save output to a file:\n\n```bash\ngoswagger -q admin -t 5 -o results/output.txt\n```\n\nLimit the crawl to a small number of SwaggerHub pages:\n\n```bash\ngoswagger -q swagger -m 2\n```\n\n## Local Test Server\n\nRun the bundled development server for local scanner testing while developing:\n\n```bash\ngo run ./testserver/cmd\n```\n\nEnvironment variables:\n\n| Variable                 | Description                                         |\n| ------------------------ | --------------------------------------------------- |\n| `TESTSERVER_PORT`        | Port to listen on, defaults to `8081`               |\n| `TESTSERVER_MODE`        | `basic` or `multi`, defaults to `multi`             |\n| `TESTSERVER_BASE_PATH`   | Search endpoint path, defaults to `/apiproxy/specs` |\n| `TESTSERVER_TOTAL_COUNT` | Override the SwaggerHub `totalCount` value          |\n| `TESTSERVER_DELAY_MS`    | Add a response delay for slow-network testing       |\n\nThe dev server exposes:\n\n| Endpoint                                          | Purpose                                                   |\n| ------------------------------------------------- | --------------------------------------------------------- |\n| `/healthz`                                        | Health check endpoint                                     |\n| `/apiproxy/specs`                                 | Search endpoint used by the scanner                       |\n| `/specs/1`, `/specs/2`, `/specs/3`, `/specs/edge` | Sample bodies with different token and edge-case patterns |\n\n## Development Workflow\n\n1. Start the test server in one terminal:\n\n    ```bash\n    go run ./testserver/cmd\n    ```\n\n2. Run goswagger against the local server in another terminal:\n\n    ```bash\n    goswagger -q testquery -m 2 -b \"http://127.0.0.1:8081/apiproxy/specs?sort=BEST_MATCH\u0026order=DESC\u0026query=%s\u0026page=%d\u0026limit=100\"\n    ```\n\n3. Edit `regex.yaml`, `pkg/*.go`, or the test server, then rerun the same command to verify behavior.\n\n**Useful dev modes:**\n\n| Mode                                   | Effect                                       |\n| -------------------------------------- | -------------------------------------------- |\n| `TESTSERVER_MODE=basic`                | Return a single page and a single sample URL |\n| `TESTSERVER_MODE=multi`                | Exercise multiple pages and patterns         |\n| `TESTSERVER_DELAY_MS=500`              | Simulate a slower service                    |\n| `TESTSERVER_BASE_PATH=/apiproxy/specs` | Override the search endpoint path            |\n\n## Notes\n\n- Output is intentionally minimal.\n- Invalid regex entries are skipped during compilation.\n- The tool keeps scanning even if one pattern or one URL fails.\n\n## Credits\n\n- Original inspiration: [SwaggerSpy by UndeadSec](https://github.com/UndeadSec/SwaggerSpy)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr0x4r%2Fgoswagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fr0x4r%2Fgoswagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr0x4r%2Fgoswagger/lists"}