T09 · Insecure Skill Coding Practices
- Location
scripts/download_files.py:16- Finding
Canvas Bearer Token Sent to an Unvalidated Download URL
- Content
View full analysis
bool: """Download a file from URL to local path.""" try: headers = {"Authorization": f"Bearer {token}"} response = requests.get(url, headers=headers, stream=True, timeout=60) response.raise_for_status() ``` ```python # Get download URL try: file_obj = canvas.get_file(file.id) download_url = file_obj.url if download_file(download_url, filepath, token): ``` ### Technical Analysis The download URL comes from remotely supplied Canvas API data. The code does not validate its scheme, hostname, port, or relationship to the configured Canvas instance before attaching the password-equivalent Canvas API token to the request. Consequently, the `Authorization: Bearer ` header may be sent to a non-Canvas host. The code also does not explicitly require HTTPS. Although `requests` provides TLS verification for HTTPS by default, it does not protect credentials when the original URL itself points to an unauthorized host or uses plaintext HTTP. This behavior conflicts with the documented claim that API tokens are never exposed. Cross-origin download URLs should generally be treated as signed URLs and requested without the Canvas bearer token unless the destination has been explicitly verified as a trusted Canvas API host. ### Attack Path 1. The victim configures the Skill to use a compromised or malicious Canvas-compatible endpoint. 2. The victim invokes the course-file download feature. 3. The remote service returns a file object whose `url` points to an attacker-controlled server. 4. `download_files.py` retrieves that URL without validating its origin. 5. The script attaches the victim's Canvas API token to ...[truncated 755 chars]- Remediation
View remediation
