T09 · Insecure Skill Coding Practices
- Location
scripts/brickeconomy_cli.py:59- Finding
Unrestricted API Base URL Override Can Expose the API Key
- Content
View full analysis
Vulnerability Details
File Location:
scripts/brickeconomy_cli.py:59-65, 102, 145-146
Vulnerability Type: Arbitrary-origin credential disclosure
Risk Level: HighThe CLI permits its API base URL to be supplied through either the
--base-urlargument or theBRICKECONOMY_BASE_URLenvironment variable. It then sends theBRICKECONOMY_API_KEYvalue in thex-apikeyheader to the selected URL without validating its scheme or origin.Complete relevant code:
python def get(self, path: str, params: dict[str, Any] | None = None) -> Any: query = urllib.parse.urlencode(clean_params(params or {}), doseq=True) url = f"{self.base_url}{path}" if query: url = f"{url}?{query}" headers = {"Accept": "application/json", "x-apikey": self.api_key} return self._request("GET", url, headers)python def add_common(parser: argparse.ArgumentParser) -> None: parser.add_argument("--base-url", default=os.getenv("BRICKECONOMY_BASE_URL", DEFAULT_BASE_URL), help="BrickEconomy API base URL") parser.add_argument("--timeout", type=int, default=READ_TIMEOUT_SECONDS, help="HTTP timeout in seconds") parser.add_argument("--dry-run", action="store_true", help="Print request shape without calling BrickEconomy")python def client_from_args(args: argparse.Namespace) -> BrickEconomyClient: return BrickEconomyClient(require_api_key(), args.base_url, args.timeout)Technical Analysis
Header-based API authentication is necessary for the Skill's declared BrickEconomy functionality. However, sending that credential to an arbitrary user- or environment-controlled origin exceeds the minimum privileges required. The checked-in OpenAPI specification identifies the intended server as
https://www.brickeconomy.com/api/v1, while the implementation accepts any URL without enforcing HTTPS or validating the hostname.Consequently, a malicious command, compromised wrapper, ...[truncated 2032 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the runtime base-URL override if alternate API deployments are not a functional requirement.
- If an override is required, parse it with
urllib.parse.urlsplit()and enforce:- The
httpsscheme only. - An explicit allowlist containing
www.brickeconomy.com. - The expected
/api/v1path prefix. - No embedded username or password.
- No fragments or malformed host components.
- An approved port, normally
443.
- The
- Reject IP literals, localhost, private-network addresses, link-local addresses, and non-HTTP schemes.
- Disable redirects for authenticated requests or implement redirect handling that strips
x-apikeyunless the destination has the exact same validated origin. - Validate the destination immediately before constructing the authenticated request rather than relying only on argument parsing.
- Add tests proving that HTTP URLs, unapproved domains, embedded credentials, malformed URLs, and cross-origin redirects are rejected.
- Preserve
--dry-runbehavior without loading or displaying the actual API key. - If exposure may already have occurred, revoke and rotate the BrickEconomy API key and review account/API activity.
