T09 · Insecure Skill Coding Practices
- Location
scripts/publish_note.py:124- Finding
Unvalidated Dynamic Upload Destination Can Expose Local Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/publish_note.py:168-177andscripts/publish_note.py:124-132
Vulnerability Type: Unvalidated outbound upload destination
Risk Level: MediumVulnerable Code
python endpoint = form.pop("endpoint", "") if not endpoint: _die("Failed to obtain upload authorization: endpoint was not returned") file_id = form.get("x:file_id", "") time.sleep(RATE_LIMIT_DELAY) _info(f"[Upload] Sending file: {filename} -> {endpoint}") _multipart_upload(endpoint, form, file_path)The receiving function uses the endpoint without validating its scheme, hostname, port, or redirect behavior:
python upload_url = endpoint.rstrip("/") + "/" req = Request( upload_url, data=body, headers={"Content-Type": f"multipart/form-data; boundary={boundary}"}, method="POST", ) try: with urlopen(req, timeout=120) as resp: return resp.read()Technical Analysis
The local-image workflow obtains a signed upload form from the fixed Mowen API and then trusts the returned
endpointas the destination for the selected local file. This dynamic endpoint is part of the documented object-storage workflow and is therefore functionally necessary. However, the implementation does not enforce HTTPS or verify that the destination belongs to an approved Mowen or Alibaba OSS domain.Consequently, a compromised, malicious, or incorrectly configured API response can direct the script to transmit the complete local image and temporary signed upload fields to an arbitrary server. Python's default URL handling can also follow redirects, and redirected destinations are not revalidated.
The API Bearer key itself is not included in the multipart upload. The exposed data consists of the user-selected local file and temporary upload authorization fields such as the policy, callback, credential, signature, metadata, and file identifiers.
Attack Pa
...[truncated 1325 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the endpoint with
urllib.parse.urlparse. - Require the
httpsscheme and reject URLs containing user information, fragments, or unexpected ports. - Enforce an explicit allowlist of object-storage hostnames or hostname suffixes documented by Mowen. Perform boundary-safe matching, such as exact equality or
hostname.endswith("." + allowed_suffix), rather than substring matching. - Disable automatic redirects for multipart uploads, or validate the scheme and hostname of every redirect target before transmitting the request body.
- Reject IP literals, localhost, link-local addresses, and private network destinations unless the API explicitly documents and requires them.
- Avoid logging the full upload URL if it may ever contain query credentials.
- Add tests covering HTTP endpoints, unrelated domains, deceptive suffixes, embedded credentials, unexpected ports, IP literals, and redirects.
- Consider constraining accepted local files to caller-approved directories when the Skill runs in an agent environment.
- Parse the endpoint with
