T09 · Insecure Skill Coding Practices
- Location
logs/2026-03-14/analysis_221448.json:1- Finding
Sensitive Portfolio Records Included in the Distributed Skill
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a disclosed Eastmoney trading automation tool, but it ships sensitive portfolio records and has weak safeguards around real-money trading actions.
Install only if you are comfortable granting this skill access to a real brokerage account and browser session. Remove the bundled logs before distribution, avoid remote CDP for trading, do not enable LLM captcha OCR unless you accept sending captcha images to a third party, keep logs/screenshots protected and cleaned up, and do not use --confirm or unattended trading until the order-confirmation and result-verification logic is strengthened.
logs/2026-03-14/analysis_221448.json:1Sensitive Portfolio Records Included in the Distributed Skill
scripts/eastmoney_trading.py:727Portfolio Security Identifiers Transmitted over Plaintext HTTP
scripts/eastmoney_trading.py:1048Real-Money Order Safeguards Can Be Bypassed and Ambiguous Results Are Reported as Success
scripts/requirements.txt:1Unbounded Third-Party Dependency Versions
The captcha OCR routine base64-encodes the login captcha image and sends it to an external LLM service using an API key from environment variables. Although the taint rule frames this as env-to-network flow, the real issue is exfiltration of authentication material to a third party without strong consent or minimization; in a trading skill, even captcha images are part of the login challenge and may expose account-login context to an outside service.
logger.info("正在调用大模型识别验证码...")
with urllib.request.urlopen(req, timeout=30) as response:
result = json.loads(response.read().decode('utf-8'))
content = None
The code accepts EASTMONEY_CDP_URL from the environment and performs a request to its /json/version endpoint, then connects to the returned debugger WebSocket. If an attacker can influence this variable, the skill will connect to an arbitrary remote Chrome DevTools endpoint, granting that endpoint broad visibility and control over browser pages, cookies, session state, screenshots, and trading actions.
ws_url = None
try:
version_url = cdp_url.rstrip('/') + '/json/version'
with urllib.request.urlopen(version_url, timeout=5) as resp:
version_data = json.loads(resp.read().decode())
ws_url = version_data.get('webSocketDebuggerUrl', '')
ws_url = ws_url.replace('ws://127.0.0.1/', f'ws://{host}:9222/')
The README documents use of a local .env file containing brokerage account credentials and also states that logs and screenshots are captured automatically. In a high-risk trading skill, this increases the chance that secrets or sensitive financial data are stored locally, exposed through screenshots/logs, or accidentally committed to version control, enabling account takeover or privacy loss.
eastmoney-trading/
├── SKILL.md # Skill 说明文档
├── README.md # 本文件
├── .env # 账号密码(不要提交到 git)
├── logs/ # 日志和截图(按天切分)
│ └── YYYY-MM-DD/
│ ├── eastmoney_trading_HHMMSS.log
Referenced artifact was not completely inspected
pip3 install -r scripts/requirements.txt
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
password = os.environ.get("EASTMONEY_PASSWORD", "")
if not account or not password:
env_file = SKILL_DIR / '.env'
if env_file.exists():
logger.info(f"从 .env 文件加载配置...")
try:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
if not account or not password:
env_file = SKILL_DIR / '.env'
if env_file.exists():
logger.info(f"从 .env 文件加载配置...")
try:
with open(env_file, 'r') as f:
for line in f:
The entire skill documentation and command guidance are presented only in Chinese, with no indication that users may choose another language or that the skill is intentionally limited to a specific locale for compliance reasons. Under the policy rule, a language or locale constraint should either be optional for the user or explicitly justified.
The skill requests sensitive capabilities in practice—environment variable access, file read/write, and network/browser connectivity—but does not declare any explicit tool scope or permissions boundaries. In a trading skill that handles brokerage credentials, screenshots, logs, and live transaction actions, this omission weakens reviewability and least-privilege controls, making unintended or excessive access harder to detect and restrict.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim tesseract-ocr-eng
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
sudo apt-get install tesseract-ocr tesseract-ocr-chi-sim tesseract-ocr-eng
The JSON contains user-facing suggestion strings entirely in Chinese, indicating the skill presents output in a fixed language. Under the policy, forcing a specific language without user opt-in or documented justification is a natural-language policy violation.
This JSON file includes natural-language suggestions exclusively in Chinese, with no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-speaking context. Per the policy, forcing a specific language without opt-in is a natural-language policy violation.
The JSON includes natural-language suggestion strings only in Chinese across L110-L119. For a general analysis artifact, this imposes a specific language/locale on users without any visible opt-in, alternative, or documented regional limitation, which matches the language/locale policy violation category.
Captcha images are transmitted to an external OCR/LLM provider during a brokerage login flow without an explicit just-in-time disclosure or confirmation. In this context, the skill handles live securities accounts and real-money trading, so third-party transfer of login challenge material is especially sensitive and increases privacy, compliance, and account-takeover risk.
The skill description says it supports 条件选股 as a functional capability. However, cmd_select merely navigates to the screening site, saves a screenshot, and prints guidance text; it never applies the CLI condition arguments or invokes the extraction logic to produce actual screening output.
The docstring actively states that the command uses 东方财富 conditions and supports technical, fundamental, market, and sector filters. In reality, the function ignores args.condition, args.market, args.industry, and args.concept and only opens the homepage and prints advice, which contradicts the stated behavior.
This JSON file contains user-facing suggestion strings entirely in Chinese, with no indication that the user can choose another language or that the locale is intentionally constrained. Under the policy, hard-coded language output without user opt-in is a natural-language locale violation.
The JSON contains user-facing suggestion strings entirely in Chinese, which imposes a specific language on the user. Under the policy rule, this is a locale/language constraint without visible opt-in or documented justification in the file.
The dependency is specified with a lower bound only, which allows future unreviewed versions to be installed and makes builds non-reproducible. In a trading automation skill, this increases supply-chain risk because changes in browser automation libraries can affect authentication and transaction flows in security-sensitive ways.
playwright>=1.40.0
Pillow>=10.0.0
pytesseract>=0.3.10
requests>=2.31.0
Pillow is unpinned, so installations may resolve to different versions over time, including versions with known security defects or behavioral changes. Because this skill performs captcha/image handling for brokerage login, image-processing code is part of a sensitive trust boundary and increases the relevance of dependency risk.
playwright>=1.40.0
Pillow>=10.0.0
pytesseract>=0.3.10
requests>=2.31.0
pandas>=2.0.0
Pillow has multiple published advisories, and because the manifest does not pin a version, there is no way to verify whether deployments are using a patched release. In this skill, Pillow likely processes captcha or login-related images, so a vulnerable image library could expose the host through crafted image inputs or denial-of-service conditions.
Using a non-pinned pytesseract version permits uncontrolled upgrades and non-reproducible builds, which can introduce vulnerable or incompatible releases. In this skill, OCR is used around authentication workflows, so dependency instability can affect a high-risk operation path.
playwright>=1.40.0
Pillow>=10.0.0
pytesseract>=0.3.10
requests>=2.31.0
pandas>=2.0.0
Requests is declared with only a minimum version, so dependency resolution may pull in unreviewed versions and obscure whether known fixes are present. Since the skill automates financial trading and may handle credentials or session traffic, supply-chain and transport-library uncertainty is more concerning than in a low-risk utility.
playwright>=1.40.0
Pillow>=10.0.0
pytesseract>=0.3.10
requests>=2.31.0
pandas>=2.0.0
Requests has known advisories, but the lack of version pinning makes it impossible to determine whether an installed environment includes the fixes. For a brokerage trading skill that may manage authenticated sessions and sensitive account data, uncertainty around the HTTP client version raises the risk of credential leakage or transport-related issues.
Pandas is not pinned, which creates non-reproducible environments and allows future versions to be installed without review. Although pandas is less central to direct network access, this skill uses it in a financial/trading context where reliability and controlled dependencies still matter.
Pillow>=10.0.0
pytesseract>=0.3.10
requests>=2.31.0
pandas>=2.0.0
No suspicious patterns detected.