T09 · Insecure Skill Coding Practices
- Location
openkm_cli.py:15- Finding
OpenKM Basic Authentication Credentials May Be Transmitted over Cleartext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
openkm_cli.py:15-18, 26-30
Vulnerability Type: Insecure transport of reusable credentials and sensitive repository data
Risk Level: MediumVulnerable Code
python class OpenKMClient: def __init__(self, base_url, username, password, debug=False): if base_url.rstrip("/").endswith("/OpenKM"): raise OpenKMError("OPENKM_BASE_URL must NOT end with /OpenKM") self.base_url = base_url.rstrip("/") self.auth = HTTPBasicAuth(username, password) self.debug = debug def _req(self, method, endpoint, **kw): url = self.base_url + endpoint self._dbg(f"{method} {url}") r = requests.request(method, url, auth=self.auth, timeout=30, **kw) self._dbg(f"→ {r.status_code} {r.text[:200]}") return rTechnical Analysis
The client accepts
OPENKM_BASE_URLwithout validating or enforcing its URL scheme. The only constructor validation rejects a base URL ending in/OpenKM; anhttp://URL remains valid.Every REST request then uses
HTTPBasicAuth, which sends a reusable Base64-encoded username and password in theAuthorizationheader. Base64 is not encryption. If the configured endpoint uses HTTP rather than HTTPS, an attacker with network visibility can read the credentials directly. Document uploads, downloaded content, metadata, search results, and workflow information may also be observed or modified in transit.The documentation presents an HTTPS URL as an example but does not enforce HTTPS in code or explicitly prohibit unencrypted HTTP.
Attack Path
- An operator or automated Agent configures
OPENKM_BASE_URLwith anhttp://OpenKM endpoint. - The CLI reads
OPENKM_USERNAMEandOPENKM_PASSWORDand constructs anHTTPBasicAuthobject. - The operator invokes any CLI command that calls
_req(). - The request sends the Basic Authentication header ...[truncated 1028 chars]
- An operator or automated Agent configures
- Remediation
View remediation
Remediation Suggestions
- Parse
OPENKM_BASE_URLwithurllib.parse.urlparseand require thehttpsscheme before constructing the client or sending credentials. - Reject missing, malformed, protocol-relative, and unencrypted URLs with a clear error message.
- If HTTP is necessary for isolated local development, require an explicit opt-in such as
OPENKM_ALLOW_INSECURE_HTTP=1. Prefer limiting this exception to loopback hosts and emit a prominent warning. - Update
SKILL.mdandREADME.txtto state that HTTPS is mandatory in production because Basic Authentication does not protect credentials without TLS. - Preserve TLS certificate verification and do not introduce
verify=False. If a private certificate authority is used, support an explicit CA bundle instead. - Use a least-privileged OpenKM service account rather than an administrative account, and rotate credentials that may previously have been used over HTTP.
- Consider token-based or short-lived authentication if supported by the deployed OpenKM environment.
Example scheme enforcement:
python from urllib.parse import urlparse parsed = urlparse(base_url) if parsed.scheme != "https": raise OpenKMError("OPENKM_BASE_URL must use HTTPS") if not parsed.netloc: raise OpenKMError("OPENKM_BASE_URL must be an absolute URL")- Parse
