T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/deregister.py:33
- Finding
- Consul ACL Token Can Be Sent to Arbitrary Destinations over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deregister.py:33-49` **Additional Relevant Locations**: `scripts/deregister.py:86-88`, `scripts/deregister.py:103-110`; `SKILL.md:58-61`, `SKILL.md:91` **Vulnerability Type**: Unrestricted credential forwarding and plaintext transmission of sensitive authentication data **Risk Level**: High ### Vulnerable Code ```python def build_url(agent: str, service_id: str) -> str: if not agent.startswith("http"): agent = "http://" + agent return agent.rstrip("/") + CONSUL_DEREGISTER_PATH + service_id def deregister(agent: str, service_id: str, token: str = None, dry_run: bool = False) -> dict: url = build_url(agent, service_id) if dry_run: return {"agent": agent, "service_id": service_id, "url": url, "status": "DRY_RUN", "ok": True} try: req = urllib.request.Request(url, method="PUT") if token: req.add_header("X-Consul-Token", token) with urllib.request.urlopen(req, timeout=10) as resp: status = resp.status ok = status == 200 return {"agent": agent, "service_id": service_id, "url": url, "status": status, "ok": ok} ``` The affected destinations and token are accepted from user-controlled command-line inputs: ```python parser.add_argument("--agents-file", help="File with one agent address per line") parser.add_argument("--from-curl", help="Raw curl command(s) to parse and replay") parser.add_argument("--token", help="Consul ACL token (X-Consul-Token header)") ``` ```python if args.from_curl: parsed = parse_curl_commands(args.from_curl) if not parsed: print("❌ No valid consul deregister curl commands found in input.", file=sys.stderr) sys.exit(1) tasks = [(p["agent"], p["service_id"]) for p in parsed] else: if not args.service_id: parser.error("--service-id is required unless using --from-curl") agents = list(args.agents or []) if args.agents_file: ...[truncated 3111 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require HTTPS when authentication is used** - Reject any `http://` destination whenever an ACL token is supplied. - Do not silently convert an address without a scheme to HTTP. - Prefer making HTTPS mandatory by default and require an explicit, prominently warned development-only option for plaintext operation. 2. **Restrict credential recipients** - Parse destinations using `urllib.parse.urlsplit()`. - Permit only the exact `https` scheme for authenticated requests. - Reject embedded credentials, fragments, malformed hosts, and unexpected ports. - Validate destination hostnames or IP addresses against an explicit operator-managed allowlist of approved Consul agents or trusted network ranges. - Resolve and validate hostnames carefully if restrictions are intended to prevent access to untrusted or internal destinations. 3. **Limit batch credential propagation** - Display the validated destination list before authenticated batch execution. - Require explicit confirmation before sending one token to multiple agents. - Consider using destination-specific credentials where operationally practical. 4. **Avoid command-line token exposure** - Read the token from a protected environment variable, restricted-permission file, standard input, or secret manager. - If backward compatibility requires `--token`, deprecate it and warn that command-line arguments can be exposed through process listings and logs. - Ensure tokens are never included in normal, JSON, exception, or debug output. 5. **Harden TLS behavior** - Retain certificate and hostname verification. - Support a configurable trusted CA bundle for private Consul deployments rather than disabling verification. - Document the expected certificate trust model and secure deployment procedure. 6. **Apply least-privilege ACL policies** - Use a narrowly scoped Consul token that authorizes only the service deregistration operati ...[truncated 508 chars]
