T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/scan_base.py:286
- Finding
- Basescan API Key Exposed Through Command-Line Arguments and URL Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan_base.py:240` and `scripts/scan_base.py:286-292` **Vulnerability Type**: API credential exposure through process arguments, shell history, and URL query parameters **Risk Level**: Medium ### Vulnerable Code ```python url = f"{BASESCAN_API}?module=token&action=tokenholderlist&contractaddress={addr}&page=1&offset=50&apikey={basescan_key}" data = fetch_json(url) ``` ```python parser.add_argument("--basescan-key", default=None, help="Basescan API key for holder data") args = parser.parse_args() # ... elif args.mode == "holders": if not args.addr: print("Error: --mode holders requires an address") sys.exit(1) scan_holders(args.addr, args.basescan_key) ``` ### Technical Analysis The script requires users to supply a Basescan API key through the `--basescan-key` command-line argument. Secrets passed through command-line arguments can be exposed through: - Shell history files. - Process inspection utilities such as `ps`, `/proc/<pid>/cmdline`, or process-monitoring software. - Job runners, orchestration systems, terminal recordings, and diagnostic logs that record complete commands. - Support bundles or CI logs containing command invocations. The key is subsequently interpolated directly into a URL query string. Although the endpoint uses HTTPS and therefore encrypts the URL in transit, query parameters may still be retained by the destination service, HTTP client instrumentation, proxies, monitoring systems, exception reports, or application logs. This implementation also conflicts with `references/api-endpoints.md`, which identifies the `BASESCAN_API_KEY` environment variable as the expected key source. The script does not read that variable. No evidence was found that the script intentionally sends unrelated sensitive local information. Its network requests target fixed services that are directly relevant to the declared on-chain scanning functionality. The network b ...[truncated 1794 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `--basescan-key` command-line option and read the key from an environment variable: ```python import os basescan_key = os.environ.get("BASESCAN_API_KEY") ``` 2. If interactive entry is required, use `getpass.getpass()` so the key is not echoed or stored in shell history: ```python from getpass import getpass basescan_key = getpass("Basescan API key: ") ``` 3. Prefer an HTTP authentication header if Basescan supports one. If the service requires an `apikey` query parameter, ensure that application logging and telemetry redact that parameter. 4. Sanitize exception messages and request diagnostics so complete URLs containing credentials are never printed or persisted. 5. Document secure secret injection for local, CI, and scheduled executions. Avoid placing the key directly in command strings, source files, or repository configuration. 6. Rotate any key previously supplied through `--basescan-key`, particularly if the script was run in shared environments, CI systems, recorded terminals, or monitored hosts. 7. Apply provider-side restrictions where available, including minimum required API permissions, rate limits, and key rotation. ]]>
