T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/zworker_api.py:22
- Finding
- Unauthenticated Localhost API Used for Privileged Automation Control<![CDATA[ ## Vulnerability Details **File Location**: `scripts/zworker_api.py:22, 29-90`; related security assumptions in `SKILL.md:126-132` **Vulnerability Type**: Unauthenticated plaintext control channel **Risk Level**: Medium ### Complete Code Snippet ```python BASE_URL = "http://localhost:18803" TIMEOUT = 10 # seconds def _make_request(method: str, endpoint: str, params: Optional[Dict] = None, data: Optional[Dict] = None) -> Dict[str, Any]: """ Send an HTTP request to the zworker API. """ url = f"{BASE_URL}{endpoint}" if HAS_REQUESTS: try: if method.upper() == 'GET': response = requests.get(url, params=params, timeout=TIMEOUT) else: headers = {'Content-Type': 'application/json'} response = requests.post( url, params=params, json=data, headers=headers, timeout=TIMEOUT ) response.raise_for_status() result = response.json() except requests.exceptions.RequestException as e: raise ZworkerAPIError(f"HTTP request failed: {e}") except json.JSONDecodeError as e: raise ZworkerAPIError(f"Response JSON parsing failed: {e}") else: try: if params: from urllib.parse import urlencode url = f"{url}?{urlencode(params)}" req_data = None headers = {} if method.upper() == 'POST' and data: req_data = json.dumps(data).encode('utf-8') headers = {'Content-Type': 'application/json'} req = urllib.request.Request( url, data=req_data, headers=headers, method=method.upper() ) with urllib.request.urlopen(req, timeout=TIMEOUT) as response: response_data ...[truncated 3234 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require a cryptographically random, per-installation API credential and send it in an authorization header. 2. Store the credential using an operating-system credential manager rather than in source code or command-line arguments. 3. Prefer an authenticated Unix-domain socket with restrictive filesystem permissions where platform support permits it. 4. If TCP must be used, bind explicitly to the loopback interface and verify that the zworker service never listens on external interfaces. 5. Consider TLS with certificate pinning or another server-authentication mechanism when the API crosses a meaningful process or container boundary. 6. Validate responses against endpoint-specific schemas, including expected types, permitted fields, size limits, and bounded list lengths. 7. Apply maximum response-body limits before JSON parsing. 8. Run the zworker service and Skill with the minimum permissions required. 9. Reject operations when authentication or service identity verification fails rather than falling back to unauthenticated behavior. ]]>
