T09 · Insecure Skill Coding Practices
- Location
scripts/odoo_client.py:174- Finding
Unrestricted endpoint configuration can disclose Odoo credentials over plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
scripts/odoo_client.py:174-177, 199-211, 228-258;scripts/login.py:61-76, 86-91;scripts/report.py:72-79
Vulnerability Type: Insufficient endpoint validation and plaintext transmission of authentication secrets
Risk Level: HighVulnerable Code
python # scripts/odoo_client.py:174-177 def normalize_url(url: str) -> str: """Normalize the system address and add HTTPS when no scheme is supplied.""" url = (url or "").strip().rstrip("/") if url and not url.startswith(("http://", "https://")): url = "https://" + url return urlpython # scripts/odoo_client.py:199-211 def authenticate(self) -> int: if not (self.url and self.db and self.login and self.secret): raise OdooError( "Credentials have not been initialized." ) try: if self.transport == "jsonrpc": self.uid = self._jsonrpc( "common", "authenticate", [self.db, self.login, self.secret, {}] ) else: common = xmlrpc.client.ServerProxy(f"{self.url}/xmlrpc/2/common") self.uid = common.authenticate(self.db, self.login, self.secret, {})python # scripts/odoo_client.py:228-258 def _jsonrpc(self, service: str, method: str, args: list): payload = { "jsonrpc": "2.0", "method": "call", "params": {"service": service, "method": method, "args": args}, "id": 1, } req = urllib.request.Request( f"{self.url}/jsonrpc", data=json.dumps(payload).encode("utf-8"), headers={"Content-Type": "application/json"}, ) with urllib.request.urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode("utf-8")) if data.get("error"): err = data["error"] msg = err.get("data", {}).get("message") or err.get("message") or str(err) ...[truncated 4963 chars]- Remediation
View remediation
Remediation Suggestions
- Enforce an exact endpoint allowlist before storing configuration and again immediately before every request:
- Scheme:
https - Hostname:
test.heysleep.cn - Database:
test - Port: default HTTPS port unless an explicitly approved alternative is required
- Scheme:
- Reject URLs containing embedded credentials, unexpected ports, fragments, or nonempty paths.
- Remove support for
http://; do not silently downgrade or accept plaintext transport. - Apply the same validation to values loaded from files and environment variables, not only interactive input.
- Centralize request construction so XML-RPC, JSON-RPC, and web-session authentication cannot bypass the policy.
- If custom endpoints are a legitimate future requirement, require an explicit administrative opt-in and clearly warn before transmitting credentials.
- Prefer scoped, revocable Odoo API keys rather than primary account passwords.
- Consider TLS certificate pinning or organization-managed trust configuration where the deployment model permits it.
- Enforce an exact endpoint allowlist before storing configuration and again immediately before every request:
