T09 · Insecure Skill Coding Practices
- Location
scripts/vbrokers_client.py:29- Finding
Hardcoded AES Key and Unauthenticated Credential Transport
- Content
View full analysis
str: aes_key = base64.b64decode(AES_KEY_B64) cipher = AES.new(aes_key, AES.MODE_ECB) padded = pad(plain_password.encode("utf-8"), AES.block_size) encrypted = cipher.encrypt(padded) return base64.b64encode(encrypted).decode("utf-8") def call(path: str, params: dict = None) -> dict: body = {"timeout_sec": TIMEOUT_SEC} if params: body["params"] = params data = json.dumps(body).encode("utf-8") req = urllib.request.Request(f"{GATEWAY_URL}{path}", data=data, method="POST") req.add_header("Content-Type", "application/json") try: resp = urllib.request.urlopen(req, timeout=TIMEOUT_SEC + 2) return json.loads(resp.read().decode("utf-8")) except urllib.error.HTTPError as e: return {"ok": False, "err": f"HTTP {e.code}: {e.reason}", "data": None} except Exception as e: return {"ok": False, "err": str(e), "data": None} def trade_login(password: str) -> dict: encrypted_pwd = encrypt_password(password) return call("/trade/TradeLogin", {"password": encrypted_pwd}) ``` ### Technical Analysis The client embeds the AES key used to encrypt the trading password directly in its source code. Anyone who obtains the Skill can recover the key by Base64-decoding `AES_KEY_B64`. The use of AES-ECB provides no semantic security between identical plaintext blocks, while the final Base64 operation is only an encoding step and offers no additional confidentiality. The encrypted password is submitted to `http://127.0.0.1:11111` without TLS or application-level authentication of the gateway. Restricting the destination to loopback substantially limi ...[truncated 1659 chars]- Remediation
View remediation
