T09 · Insecure Skill Coding Practices
- Location
scripts/upload_media.py:24- Finding
Bearer Token and Uploaded File Exposed Through Forced Plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
scripts/upload_media.py, lines 24-53
Vulnerability Type: Plaintext transmission of credentials and user-selected file contents
Risk Level: HighVulnerable Code:
python bridge = config["plugins"]["entries"]["astron-claw"]["config"]["bridge"] host = urlparse(bridge["url"]).netloc token = bridge["token"] return {"host": host, "token": token}python url = f"http://{config['host']}/api/media/upload" filename = os.path.basename(file_path) with open(file_path, "rb") as f: resp = requests.post( url, headers={"Authorization": f"Bearer {config['token']}"}, files={"file": (filename, f)}, data={"sessionId": session_id} if session_id else {}, )Technical Analysis
The script parses the configured bridge URL but preserves only its network location. It then reconstructs the upload endpoint with a hardcoded
http://scheme. This discards any configured HTTPS scheme and forces the bearer token, uploaded file, filename, and optional session identifier to travel over an unencrypted connection.Because bearer tokens grant access to whoever possesses them, an attacker who can observe the network traffic can reuse the captured token without needing additional authentication. An active network attacker can also modify requests or responses, including substituting the returned public download URL.
Reading a bridge credential and transmitting a caller-selected file are relevant to the declared authenticated-upload function. However, transmitting them over plaintext HTTP is not necessary and fails least-security expectations.
Attack Path
- A user invokes the Skill with a local file to upload.
- The script reads the Astron Claw Bridge bearer token from
/root/.openclaw/openclaw.json. - Even if the configured bridge URL uses HTTPS, the script removes that scheme and constructs an HTTP endpoint.
- T ...[truncated 1203 chars]
- Remediation
View remediation
Remediation Suggestions
- Preserve and validate the configured URL rather than extracting only its network location.
- Require HTTPS for every authenticated upload and reject plaintext HTTP configuration.
- Reject malformed URLs, credentials embedded in URLs, fragments, and unexpected schemes.
- Construct the API endpoint from a validated HTTPS base URL.
- Configure a finite connection and response timeout.
- Keep TLS certificate verification enabled and do not introduce
verify=False. - Consider restricting the bridge destination to an explicit allowlist if only known service origins are legitimate.
- Avoid printing unrestricted server response bodies on errors because they may contain sensitive diagnostics.
- Warn users that uploaded files will become publicly accessible and obtain clear confirmation before uploading sensitive files.
Example hardened construction:
python bridge_url = bridge["url"].rstrip("/") parsed = urlparse(bridge_url) if parsed.scheme != "https" or not parsed.netloc: raise ValueError("Bridge URL must be a valid HTTPS URL") if parsed.username or parsed.password or parsed.fragment: raise ValueError("Bridge URL contains prohibited components") url = f"{bridge_url}/api/media/upload" resp = requests.post( url, headers={"Authorization": f"Bearer {config['token']}"}, files={"file": (filename, f)}, data={"sessionId": session_id} if session_id else {}, timeout=(10, 120), )
