T09 · Insecure Skill Coding Practices
- Location
r2.py:158- Finding
Signed Authorization Headers May Be Forwarded to an Unvalidated Redirect Destination
- Content
View full analysis
Vulnerability Details
File Location:
r2.py, lines 158–174
Vulnerability Type: Authorization header exposure through automatic cross-origin redirects
Risk Level: Highpython _validate_url(url) headers = _aws_headers(method, canonical_uri, query, body) req = urllib.request.Request( url, data=body if body else None, headers=headers, method=method, ) # Create restricted opener (HTTPS only) opener = urllib.request.build_opener( urllib.request.HTTPSHandler() ) try: with opener.open(req, timeout=30) as resp: # nosec B310 return resp.status, resp.read()Technical Analysis
The code validates only the initial URL before creating the request. The opener constructed by
urllib.request.build_opener()includes standard redirect handling in addition to the explicitly supplied HTTPS handler. Redirect destinations are therefore not passed through_validate_url().Request headers supplied through the
Requestconstructor can be copied to a redirected request. This may include the AWS Signature Version 4Authorizationheader, the R2 access-key identifier contained in its credential scope,x-amz-date, andx-amz-content-sha256.HTTPS enforcement alone does not prevent disclosure because an attacker-controlled redirect destination can also use HTTPS. Moreover, the current hostname check at line 139 uses:
python if not parsed.netloc.endswith("cloudflarestorage.com"): raise ValueError("Unexpected host")A suffix comparison without a hostname boundary is weaker than comparison against the exact expected R2 hostname. Validation should use
parsed.hostnameand an exact allowlist.Attack Path
- A user invokes an operation such as
download,list, ordelete. _aws_headers()generates a signed request containing the access-key identifier and AWS Signature Version 4 authentication material.- The Cloudflare endpoint, ...[truncated 1289 chars]
- A user invokes an operation such as
- Remediation
View remediation
Remediation Suggestions
- Disable automatic redirects by installing a custom
urllib.request.HTTPRedirectHandlerthat rejects every redirect. - If redirects are operationally required, validate every redirect target before following it.
- Require
parsed.scheme == "https"and compareparsed.hostnameagainst the exact expected hostname:python expected_host = f"{ACCOUNT_ID}.r2.cloudflarestorage.com" if parsed.scheme != "https" or parsed.hostname != expected_host: raise ValueError("Unexpected destination") - Reject URLs containing user information, unexpected ports, fragments, or other authority ambiguity.
- Never forward an existing
Authorizationheader across origins. - Regenerate the AWS Signature Version 4 header only after an approved redirect destination and canonical request have been validated.
- Add automated tests covering cross-origin redirects, same-origin redirects, HTTPS-to-HTTP redirects, suffix-confusion hostnames, and redirects containing user information.
- Disable automatic redirects by installing a custom
