T09 · Insecure Skill Coding Practices
- Location
scripts/common/ocr_client.py:158- Finding
Cross-Origin Redirects Can Forward the API Key and Sensitive Image Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/common/ocr_client.py:158-180
Vulnerability Type: Sensitive data exposure through unrestricted HTTP redirects
Risk Level: MediumVulnerable Code
python def _build_request_param(self, image_url: str = None, base64_data: str = None) -> Dict[str, Any]: """构建请求参数""" param = { "aiApiKey": self.api_key, "dataType": self.data_type, "scene": self.scene } if base64_data: param["dataBase64"] = base64_data else: param["dataUrl"] = image_url return param def _send_request(self, param: Dict[str, Any]) -> requests.Response: """发送 HTTP 请求到 OCR API""" headers = {"Content-Type": "application/json", "X-Appbuilder-From": "openclaw"} response = self.session.post( API_URL, json=param, headers=headers, timeout=REQUEST_TIMEOUT, allow_redirects=True ) return responseTechnical Analysis
The API key is included in the JSON request body together with either the Base64-encoded image or its URL. The request explicitly enables automatic redirects without validating the destination of the redirected request.
HTTP status codes such as 307 and 308 preserve the original request method and body. Therefore, if the configured OCR endpoint returns a cross-origin 307 or 308 redirect, the
requestsclient can resend the POST body—includingaiApiKeyanddataBase64—to the redirected destination.This requires the legitimate endpoint, its surrounding infrastructure, or an equivalent trusted network component to be compromised or misconfigured. It is not evidence of intentional exfiltration: the Base64 conversion itself is necessary JSON serialization for the declared OCR functionality. The vulnerability is the unrestricted forwarding of that sensitive body after a redirect.
Attack Path
- A user invokes the Skill with a ...[truncated 1107 chars]
- Remediation
View remediation
Remediation Suggestions
- Disable automatic redirects for requests carrying credentials or image data:
python response = self.session.post( API_URL, json=param, headers=headers, timeout=REQUEST_TIMEOUT, allow_redirects=False ) - Treat any 3xx response as an error unless redirects are explicitly required by the service contract.
- If redirects are necessary, process them manually and require:
- HTTPS for every destination.
- An exact hostname allowlist.
- The expected port.
- No embedded URL credentials.
- No downgrade from HTTPS to HTTP.
- Revalidation at every redirect hop.
- Never resend the API key or image body when the origin changes.
- Prefer transmitting credentials through an authorization header, while still explicitly preventing credential forwarding across origins.
- Add regression tests using 302, 303, 307, and 308 responses to verify that sensitive data never reaches an unapproved host.
- Disable automatic redirects for requests carrying credentials or image data:
