T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/caldav.py:114
- Finding
- Apple credentials can be disclosed to untrusted server-provided hosts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/caldav.py`, lines 48–60, 114–116, 133–136, 184, 227–228, and 404–405 **Vulnerability Type**: Insufficient destination validation for authenticated network requests **Risk Level**: High ### Vulnerable Code ```python self.base_url = "https://caldav.icloud.com" self.session = requests.Session() self.session.auth = self.auth self.session.headers.update({ 'Content-Type': 'text/xml; charset=utf-8' }) ``` ```python # If principal is full URL, extract base if principal.startswith('https://'): parsed = urlparse(principal) self.base_url = f"{parsed.scheme}://{parsed.netloc}" principal = parsed.path ``` ```python if href.startswith('https://'): self._calendar_home = href parsed = urlparse(href) self.base_url = f"{parsed.scheme}://{parsed.netloc}" return href ``` ```python 'url': self.base_url + href if not href.startswith('https') else href, ``` ```python event_url = self.base_url + href if not href.startswith('https') else href event_response = self.session.get(event_url) ``` ```python event_url_full = self.base_url + href if not href.startswith('https') else href event_response = self.session.get(event_url_full) ``` ### Technical Analysis The client stores the Apple ID and app-specific password as Basic Authentication credentials on a shared `requests.Session`. Requests made through that session can therefore include the credentials automatically. Although the initial destination is `https://caldav.icloud.com`, absolute URLs returned in CalDAV XML responses are trusted based only on whether they begin with `https://`. The hostname, port, and relationship to the Apple CalDAV service are not validated. A server-provided principal, calendar-home URL, calendar URL, or event URL can consequently redirect subsequent authenticated requests to another HTTPS origin. This behavior exceeds the declared minimum privilege boundary. The Skill documentation states that credentials ...[truncated 1368 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define an explicit allowlist for `caldav.icloud.com` and documented Apple CalDAV shard hostname patterns. 2. Before every request, parse the final URL and validate: - The scheme is exactly `https`. - The hostname is an approved Apple CalDAV hostname. - The port is absent or is the expected HTTPS port. - User-information fields, fragments, and malformed host representations are absent. 3. Do not update `self.base_url` from an absolute response URL until its origin has passed validation. 4. Reject untrusted absolute `href` values rather than sending an authenticated request to them. 5. Disable redirects or inspect each redirect destination before following it. Never forward authentication across origins. 6. Consider constructing authorization headers only after destination validation instead of storing credentials globally on a reusable session. 7. Add tests covering external hosts, deceptive suffixes, nonstandard ports, encoded host representations, and cross-origin redirects. ]]>
