T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/smartbill_cli.py:57
- Finding
- SmartBill credentials and invoice data can be transmitted to an arbitrary endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/smartbill_cli.py`, lines 57-59, 108-110, 125-127, and 153-158 **Vulnerability Type**: Unrestricted authentication endpoint configuration **Risk Level**: High ### Vulnerable Code ```python username = args.username or os.getenv("MAVERICK_SMARTBILL_USERNAME") token = args.token or os.getenv("MAVERICK_SMARTBILL_TOKEN") base_url = args.base_url if args.base_url is not None else os.getenv("MAVERICK_SMARTBILL_API_BASE", DEFAULT_BASE_URL) ``` ```python def __init__(self, config: ClientConfig): self.config = config auth_value = f"{config.username}:{config.token}".encode("utf-8") self._auth_header = f"Basic {base64.b64encode(auth_value).decode('ascii')}" ``` ```python url = f"{self.config.base_url}{path}" if query: compact_query = {k: v for k, v in query.items() if v is not None} ``` ```python request = Request(url=url, data=payload, headers=headers, method=method) try: with urlopen(request, timeout=self.config.timeout_seconds) as response: response_body = response.read() ``` ### Technical Analysis The API base URL can be supplied through either `--base-url` or the `MAVERICK_SMARTBILL_API_BASE` environment variable. The implementation only checks that the resulting value is non-empty. It does not validate: - That the URL uses HTTPS. - That the destination host is `ws.smartbill.ro`. - That redirects remain on the trusted host. - That a custom endpoint has been explicitly approved for testing. The client constructs an HTTP Basic Authorization header containing the SmartBill username and API token and attaches it to requests sent to the selected base URL. Creating an invoice also sends the complete invoice payload, which may contain customer names, addresses, email addresses, VAT identifiers, product information, and financial data. Base64 encoding at lines 109-110 is normal HTTP Basic authentication and is not encryption. If the configured destination is controlled by an att ...[truncated 1766 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce HTTPS and an explicit hostname allowlist for normal operation: ```python from urllib.parse import urlparse parsed = urlparse(base_url) if parsed.scheme != "https": raise CliError("SmartBill API base URL must use HTTPS.") if parsed.hostname != "ws.smartbill.ro": raise CliError("SmartBill API host must be ws.smartbill.ro.") ``` 2. Prefer removing `--base-url` from production-facing commands. If custom endpoints are required for development, place them behind an explicit option such as `--allow-custom-endpoint`. 3. Never send production credentials to a custom endpoint. Require separately supplied test credentials when custom endpoint mode is enabled. 4. Prevent cross-origin credential forwarding during redirects. Disable automatic redirects or verify that every redirect target retains the approved HTTPS scheme and hostname before resending authentication. 5. Normalize and validate the URL, including scheme, hostname, port, username information, and malformed or ambiguous URL forms. 6. Document that environment variables controlling network destinations are security-sensitive and must not be populated from untrusted agent instructions, invoice files, or user-provided payload fields. 7. Add tests confirming rejection of: - Plaintext HTTP URLs. - Non-SmartBill hosts. - URLs containing embedded user information. - Redirects to unapproved hosts. - Hostname-confusion values such as `ws.smartbill.ro.attacker.example`. ]]>
