T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/n8n_api.py:19
- Finding
- API Key Exposure Through Unvalidated Transport and Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/n8n_api.py`, lines 19-34 **Vulnerability Type**: Unvalidated endpoint and insecure credential transmission **Risk Level**: High ### Vulnerable Code ```python def __init__(self, base_url: str = None, api_key: str = None): self.base_url = base_url or os.getenv('N8N_BASE_URL') self.api_key = api_key or os.getenv('N8N_API_KEY') if not self.api_key: raise ValueError("N8N_API_KEY not found in environment") self.session = requests.Session() self.session.headers.update({ 'X-N8N-API-KEY': self.api_key, 'Accept': 'application/json', 'Content-Type': 'application/json' }) def _request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]: """Make API request""" url = f"{self.base_url}/api/v1/{endpoint.lstrip('/')}" response = self.session.request(method, url, **kwargs) ``` ### Technical Analysis The client obtains `N8N_BASE_URL` from an environment variable without validating its scheme, hostname, port, or embedded credentials. It then places the n8n API key in a persistent session header and sends requests to the resulting URL. Consequently, an `http://` base URL causes the API key and API traffic to be transmitted without transport encryption. An attacker able to observe or modify the network path could capture the key or alter API responses. The `requests` library also follows redirects by default. Because the API key is stored in the custom `X-N8N-API-KEY` session header, a redirect may cause sensitive credentials to cross the originally configured trust boundary. The implementation does not disable redirects or verify that redirect destinations retain the expected HTTPS scheme and trusted origin. ### Attack Path 1. A user configures an HTTP n8n URL, or an attacker modifies the `N8N_BASE_URL` environment variable. 2. The client constructs an API URL directly from that value. 3. The client attaches the `X-N8N-API-KE ...[truncated 1038 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the configured URL with `urllib.parse.urlparse`. 2. Require the `https` scheme and reject HTTP, non-network schemes, embedded credentials, malformed hosts, and unexpected ports. 3. Maintain an allowlist of trusted n8n hostnames where deployment constraints permit it. 4. Disable automatic redirects for authenticated requests: ```python response = self.session.request( method, url, allow_redirects=False, timeout=(5, 30), **kwargs, ) ``` 5. If redirects are operationally required, follow them manually only after confirming that the destination uses HTTPS and has exactly the expected trusted origin. 6. Avoid attaching the API key as a global session header when redirect behavior cannot be tightly controlled. Add it only after destination validation. 7. Add tests covering HTTP URLs, cross-origin redirects, HTTPS-to-HTTP redirects, embedded URL credentials, malformed URLs, and unexpected hosts. 8. Use a narrowly scoped n8n API key and rotate it immediately if it may have been transmitted through an untrusted endpoint. ]]>
