T09 · Insecure Skill Coding Practices
- Location
open-link.py:11- Finding
Hard-Coded API Signing Credential
- Content
View full analysis
Vulnerability Details
File Location:
open-link.py, lines 11–43
Vulnerability Type: Hard-coded reusable signing credential
Risk Level: MediumVulnerable Code
python APP_ID = "100003" APP_KEY = "38d2391985e2369a5fb8227d8e6cd5e5" URL = "https://autoglm-api.zhipuai.cn/agentdr/v1/assistant/skills/open-link" TOKEN_URL = "http://127.0.0.1:53699/get_token" def generate_sign(app_id: str, timestamp: int, app_key: str) -> str: raw = f"{app_id}&{timestamp}&{app_key}" return hashlib.md5(raw.encode()).hexdigest() def get_token() -> str: try: with urllib.request.urlopen(TOKEN_URL) as resp: token = resp.read().decode("utf-8").strip() except Exception as e: print(f"ERROR: Unable to obtain token from local service: {e}") sys.exit(1) if not token: print("ERROR: The obtained token is empty.") sys.exit(1) if not token.lower().startswith("bearer "): token = f"Bearer {token}" return token def open_link(link: str) -> dict: token = get_token() timestamp = int(time.time()) sign = generate_sign(APP_ID, timestamp, APP_KEY)Technical Analysis
The reusable
APP_KEYis embedded directly in the distributed source code and used to generate theX-Auth-Signvalue. Any party able to read the Skill package can recover this credential and independently generate signatures for arbitrary current timestamps.The signature is an unkeyed MD5 digest over the application ID, timestamp, and embedded key. Once the key is known, the digest provides no protection against forgery. MD5 is also a legacy hash with obsolete collision resistance, although replacing it requires corresponding server-side protocol support.
The separate bearer token remains an additional authentication requirement in the observed request flow. Therefore, possession of the exposed application key alone does not dem ...[truncated 1398 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the signing key from the Skill package and source-control history.
- Rotate the exposed key because removal alone cannot revoke copies already obtained.
- Generate signatures in a trusted backend service or retrieve the key at runtime from an operating-system secret store with narrowly scoped access.
- Do not expose the key through command-line arguments, logs, exceptions, or plaintext configuration files.
- Restrict the credential to the minimum required endpoint, application identity, quota, and lifetime.
- Add server-side timestamp expiration and nonce-based replay prevention.
- If the API protocol can be changed, replace the custom MD5 construction with a standard message-authentication mechanism such as HMAC-SHA-256.
- Retain the fixed HTTPS API destination and validate TLS certificates using the platform trust store.
