T09 · Insecure Skill Coding Practices
- Location
test_connection.py:29- Finding
Hard-Coded API Credentials Used for Authenticated Account Operations
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is related to Tencent IMA knowledge-base access, but it handles live account credentials unsafely and includes tests that can write to an account without clear safeguards.
Install only if you are comfortable giving this skill access equivalent to your active IMA session. Use a test account or limited credentials, avoid passing cookies in shell commands, do not store session cookies in plaintext, rotate any exposed API keys, and do not run endpoint write tests against important knowledge bases without reviewing the exact requests first.
test_connection.py:29Hard-Coded API Credentials Used for Authenticated Account Operations
test_cookie.py:156IMA Session Cookies Persisted in Plaintext Without Enforced Owner-Only Permissions
test_cookie.py:211Session Cookies Accepted Through Command-Line Arguments
test_endpoints.py:49Endpoint Availability Test Performs Unconfirmed Persistent Account Writes
get_ima_cookie_playwright.py:113Browser Helper Collects and Logs More Cookie Data Than Required
test_knowledge_base.py:97Private Knowledge-Base API Responses Are Dumped to Standard Output
The example reads a session cookie from ~/.hermes/.env, normalizing storage of a highly privileged browser credential in a plain local file. Plaintext env files are often world-readable through weak permissions, backups, shell tooling, accidental commits, or other local compromise, making credential theft significantly easier.
import json
# 读取 Cookie
with open(Path.home() / '.hermes' / '.env') as f:
content = f.read()
cookie = re.search(r'IMA_COOKIE=["\'](.+?)["\']', content).group(1)
The description claims a comprehensive IMA knowledge-base integration with multiple authentication modes and a wide set of management and content features. The supplied code is much narrower: it is a cookie acquisition/testing helper script. It guides the user to manually retrieve browser cookies, checks whether the cookie string contains IMA-TOKEN, calls a single endpoint to retrieve home page/knowledge-base data, and parses/display lists of personal/followed/public knowledge bases. There is no OpenAPI auth flow, no CRUD for notes, no folder manipulation, no RAG Q&A, and no broader knowledge-base or subscription management interface. This is a material mismatch in both primary purpose and implemented capabilities.
The code only covers a narrow subset of the declared functionality. It authenticates via OpenAPI headers using client_id and api_key; there is no Cookie auth path. Implemented endpoints are limited to note import/create, get content, and append content, with two convenience helpers that format note content before calling create_note. There are no APIs for deleting or updating notes (beyond append), no knowledge base administration features, no RAG/QA, no folder manipulation, and no subscription management. The primary domain is still Tencent IMA knowledge-base-related note handling, so this is not unrelated behavior, but the description materially overstates the implemented scope.
The description presents a production-style IMA knowledge-base skill with broad operational support across multiple feature areas and authentication modes. In contrast, the code chunk is specifically a batch testing utility for known /cgi-bin/ endpoints. It uses hardcoded sample payloads, checks HTTP/JSON responses, prints availability status, and writes a report file. While some tested endpoints correspond to declared areas such as notes, knowledge bases, folders, and Q&A, the code does not implement the claimed complete interface wrapper, does not support OpenAPI auth, and does not include subscription knowledge-base management. The primary purpose is materially different: endpoint validation rather than providing the described end-user/API skill functionality.
The declared description significantly overstates the functionality. The supplied code chunk is a simple diagnostic/testing script for one Cookie-authenticated endpoint that retrieves home page knowledge base data. It does not expose or implement the broad set of features claimed in the description, such as full interface coverage, dual authentication modes, CRUD operations, RAG, or folder/subscription management actions. While it is related to Tencent IMA knowledge bases, its actual purpose is much narrower and read-only, so the description does not accurately represent the behavior of this code chunk.
The skill explicitly tells users to store a live session cookie in a plaintext local .env file. Session cookies are bearer tokens; if that file is read by other tools, exposed in backups, logs, shell history, or accidentally committed, an attacker may gain direct access to the linked IMA account.
# 或者手动添加
echo 'IMA_COOKIE="你的_Cookie"' >> ~/.hermes/.env
The sample code programmatically reads the cookie from ~/.hermes/.env and injects it into request headers, establishing a direct credential-access path from local storage to outbound authenticated requests. In an agent context, reading secrets from a common env file is more dangerous because unrelated workflows or tools may gain access to that file and reuse the session token.
from pathlib import Path
# 读取 Cookie
env_file = Path.home() / ".hermes" / ".env"
content = env_file.read_text()
cookie = re.search(r'IMA_COOKIE=["\'](.+?)["\']', content).group(1)
The documentation states that harvested cookies will be automatically saved to ~/.hermes/.env, normalizing the handling of active authentication material as a local file secret. In the context of a skill whose purpose is to access a user's IMA account, this increases practical danger because it encourages users to export browser session credentials outside the browser's protection boundary.
使用方法:
python get_ima_cookie_playwright.py
Cookie获取后会自动保存到 ~/.hermes/.env
"""
import asyncio
Hardcoding the secret destination as Path.home() / '.hermes' / '.env' creates a predictable plaintext location for sensitive authentication data. Predictable storage locations make credential discovery easier for local attackers, malware, misconfigured tooling, or accidental commits and sync processes, especially when the script does not enforce secure filesystem permissions.
"""IMA Cookie 获取器"""
IMA_URL = "https://ima.qq.com"
ENV_FILE = Path.home() / ".hermes" / ".env"
def __init__(self):
self.cookie_str = None
The script extracts and stores the user's full authenticated cookie jar, including IMA-TOKEN, specifically so it can be replayed by later scripts. Full session-cookie reuse is equivalent to credential reuse in many web apps; anyone who obtains the saved value may be able to impersonate the user and access their knowledge base, notes, subscriptions, or other account data until the session expires or is revoked.
The script falls back to hardcoded client_id and api_key values when no config file is present, which exposes live-looking credentials in source code and encourages accidental use of shared secrets. If these credentials are valid, anyone with code access can authenticate to the remote IMA service and access or modify knowledge-base data without the operator realizing they are using embedded secrets.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Cookie 格式示例
IMA-TOKEN=eyJhbGc...;其他参数=xxx;...
## 验证成功后,Cookie会自动保存到 ~/.hermes/.env
"""
import requests
Defining a fixed path for storing and later loading credentials from ~/.hermes/.env encourages use of a predictable plaintext secret store for a browser session cookie. This makes credential theft easier for local malware, other users on a shared system, or accidental leakage through logs, backups, and repository operations.
"""IMA Cookie 验证器"""
BASE_URL = "https://ima.qq.com"
ENV_FILE = Path.home() / ".hermes" / ".env"
def __init__(self, cookie_str: str = None):
self.cookie_str = cookie_str or self.load_from_env()
Reading credentials from ~/.hermes/.env is credential-access behavior because the script harvests a session cookie from a local secret store and then uses it for authenticated requests. In the context of a knowledge-base skill, this is more dangerous than ordinary configuration loading because the cookie may belong to a real user account and enables access to private remote data and write actions.
"""IMA 端点测试器"""
BASE_URL = "https://ima.qq.com"
ENV_FILE = Path.home() / ".hermes" / ".env"
# 已知的 /cgi-bin/ 端点
ENDPOINTS = [
The endpoint list includes state-changing operations such as save_note and create_folder, and run_all_tests executes them automatically as part of bulk testing. Running this script can therefore create or modify remote user data without explicit acknowledgement, which is especially risky because it uses real authenticated cookies.
The guide explicitly instructs users to extract live browser authentication cookies and persist them in a local env file, but does not warn that these cookies are bearer credentials that may grant full account access. In the context of a knowledge-base skill with write and subscription capabilities, theft or mishandling of the cookie could enable unauthorized reading, modification, or takeover-like access to the user's IMA data.
The documentation shows authenticated requests that send the user's raw cookie to remote /cgi-bin/ endpoints without any privacy or credential-handling warning. Because the cookie is inserted directly into custom headers and the documented endpoints support broad knowledge-base operations, users may unknowingly expose a highly privileged session token during testing, logging, screen sharing, or reuse in unsafe scripts.
The skill documents capabilities that read environment files, write secrets to disk, and make outbound network requests, but it does not declare any explicit tool scope or permissions boundary. That makes the trust model unclear and increases the risk that a host agent executes sensitive file, env, or network actions without informed approval.
The documentation instructs users to capture browser session cookies and persist them locally, but it does not prominently warn that these cookies are bearer credentials that may grant account access if copied, logged, or reused. In this context, the skill targets a real user account and encourages manual credential extraction, which materially increases account-compromise risk.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
# 1. 获取知识库列表
resp = requests.post(
'https://ima.qq.com/cgi-bin/knowledge_tab_reader/get_home_page_data',
headers=headers,
json={"knowledge_base_id": "", "need_folder_number": True}