T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/bookstack.py:17
- Finding
- BookStack API Credentials May Be Transmitted over Cleartext HTTP## Vulnerability Details **File Location**: `scripts/bookstack.py:17, 33-39` **Vulnerability Type**: Unencrypted transmission of API credentials **Risk Level**: Medium ### Vulnerable Code ```python BASE_URL = os.getenv('BOOKSTACK_URL', '').rstrip('/') TOKEN_ID = os.getenv('BOOKSTACK_TOKEN_ID', '') TOKEN_SECRET = os.getenv('BOOKSTACK_TOKEN_SECRET', '') # ... url = f"{BASE_URL}/api/{endpoint}" # ... req = urllib.request.Request( url, headers={ "Authorization": f"Token {TOKEN_ID}:{TOKEN_SECRET}", "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "BookStack-CLI/1.0" }, method=method ) ``` ### Technical Analysis The script obtains `BOOKSTACK_URL` from the environment and uses it directly without validating its URL scheme. Consequently, a URL beginning with `http://` is accepted. Every API request includes the BookStack token ID and secret in the `Authorization` header. When HTTP is used, TLS does not protect this header, allowing an attacker with visibility into the network path to read the credentials. Network access and API authentication are necessary for the Skill's declared BookStack integration, but transmitting credentials over an unencrypted channel does not satisfy least-privilege and secure-transport requirements. The issue does not require command execution or malicious code in the repository. Exploitation depends on an HTTP configuration and an attacker able to observe or manipulate the relevant network traffic. ### Attack Path 1. The user or deployment configures `BOOKSTACK_URL` with an `http://` URL. 2. The Skill invokes a BookStack command such as `get_page`, `search`, or an update operation. 3. `api_call()` constructs an HTTP endpoint using the unvalidated base URL. 4. The script sends `BOOKSTACK_TOKEN_ID` and `BOOKSTACK_TOKEN_SECRET` in the cleartext `Authorization` header. 5. A network-positioned attacker captures the request and extracts the token. 6. The att ...[truncated 851 chars]
- Remediation
- ## Remediation Suggestions 1. Parse `BOOKSTACK_URL` with `urllib.parse.urlparse()` before making requests. 2. Require the `https` scheme and a nonempty hostname. 3. Reject unsupported schemes, malformed URLs, fragments, and embedded user information. 4. If cleartext HTTP is needed for isolated local development, require an explicit opt-in environment variable and emit a prominent warning. Restrict the exception to loopback addresses where practical. 5. Use a dedicated BookStack API identity with only the permissions necessary for the intended operations. Avoid granting delete or broad administrative permissions when only search or read access is required. 6. Document certificate-validation requirements and do not introduce an option that disables TLS verification. Example hardening: ```python parsed = urllib.parse.urlparse(BASE_URL) if parsed.scheme != "https" or not parsed.hostname: print("Error: BOOKSTACK_URL must be a valid HTTPS URL") sys.exit(1) if parsed.username or parsed.password or parsed.fragment: print("Error: BOOKSTACK_URL contains unsupported components") sys.exit(1) ```
