Back to skill

Security audit

IPO监控

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says: monitors public IPO pages, stores local history, and sends configured Feishu notifications, with some setup and disclosure caveats.

Install in a virtual environment, review and pin dependency versions if reproducibility matters, configure only approved Feishu webhook URLs, remember that IPO changes and alert text will be sent to Feishu, and use cron or daemon mode only if you want recurring background execution.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding

Unpinned Third-Party Dependencies Allow Unreviewed Package Versions

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:4-7
Related Installation Instruction: SKILL.md:21-23
Vulnerability Type: Supply-chain exposure through non-reproducible dependency resolution
Risk Level: Medium

Vulnerable code:

text
requests>=2.28.0
urllib3>=1.26.0
beautifulsoup4>=4.11.0
pyyaml>=6.0

The dependencies are installed through the following documented command:

bash
# 1. Install dependencies
pip install -r requirements.txt

Technical Analysis

Every dependency uses an open-ended minimum-version constraint. Consequently, installation resolves the latest compatible packages available from the configured Python package index at installation time rather than a fixed, previously reviewed dependency set.

This does not prove that any currently named dependency is malicious. However, it makes builds non-reproducible and permits future, unreviewed direct or transitive versions to enter the execution environment. If an upstream distribution account, package release, package index, or dependency is compromised, malicious installation-time or import-time code could execute under the installing user's account.

No hashes or lock file are supplied to authenticate the expected package artifacts.

Attack Path

  1. An attacker compromises a permitted future release, an upstream distribution account, a transitive dependency, or the package source used by pip.
  2. A user follows SKILL.md and runs pip install -r requirements.txt.
  3. pip resolves the compromised release because it satisfies the open-ended >= constraint.
  4. Malicious package installation hooks or subsequently imported code execute with the privileges of the user running pip or the monitor.
  5. The compromised code could access process-readable files and configuration, alter monitoring results, or initiate network connections.

Impact Assessment

Exploitation would provid ...[truncated 609 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact reviewed version using ==.

  2. Generate a lock file that also fixes all transitive dependency versions.

  3. Record cryptographic hashes for every permitted artifact and install with:

    bash
    python -m pip install --require-hashes -r requirements.lock
    
  4. Generate the lock file through a controlled workflow, such as pip-compile --generate-hashes, and review dependency changes before updating it.

  5. Install inside a dedicated virtual environment under an unprivileged account; do not run pip with administrator or root privileges.

  6. Use a trusted package index and prevent unintended fallback to untrusted extra indexes.

  7. Add automated dependency vulnerability and integrity scanning to the release process.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (39)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

该技能说明文档以“IPO监控技能”命名并全文固定使用中文,没有说明这是面向特定中文用户群或地区合规要求,也未提供语言/locale 选择。根据规则,若技能在自然语言层面强制特定语言而缺少用户选择或明确 justification,属于语言/locale 政策问题。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill is designed to push scraped data to Feishu, but the README does not clearly disclose this outbound transmission as an operational/data-handling behavior. In agent environments, undisclosed external transmission is security-relevant because users may run the skill without realizing data will be sent to a third-party webhook, creating confidentiality and governance risks.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The code performs an outbound HTTP POST to a Feishu webhook, which is a real external transmission path. While sending notifications is the stated purpose of the skill, it still represents a security-sensitive data egress channel because scraped records and change summaries leave the local environment and are delivered to an external service.

Content

Scanner excerpt · README.md (reported line 784)May include surrounding context.

md
}
        
        try:
            response = requests.post(url, json=payload, timeout=10)
            if response.status_code == 200:
                self.logger.info("飞书消息发送成功")
            else:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

L873-L914 的文档化示例明确描述了对 403/429 进行特殊处理、在403时更换UA、并循环重试的逻辑,但实际可见实现位于 L270-L298,仅调用 session.get 后直接 raise_for_status,对 403/429 没有专项分支,也没有 _rotate_user_agent 实现。这不是简单的文档不全,而是错误处理能力说明与代码行为直接不一致。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation explicitly configures scheduled Feishu delivery and webhook-based alerting, but it does not prominently warn users that enabling these modes causes automatic outbound network transmission to third-party services. Because execution is scheduled and unattended, users may unknowingly set up recurring external data/message exfiltration or notifications from a local environment.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

The crontab instructions create persistent scheduled execution from the user's system, which continues running outside the immediate interactive session. Persistence itself is risky in agent skills because it can cause repeated code execution, repeated network activity, and reduced user visibility, especially when logs are redirected and production mode is suggested.

Content

Scanner excerpt · SCHEDULER.md (reported line 38)May include surrounding context.

bash
# 编辑 crontab
crontab -e

# 添加定时任务(每天9点和15点运行)
0 9,15 * * * /usr/bin/python3 /Users/eurus/.openclaw/workspace/ipo-monitor-v2/main.py >> /tmp/ipo_monitor.log 2>&1

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill documentation instructs users to configure a Feishu webhook but does not clearly warn that monitored IPO data will be transmitted to an external third-party service. This can cause unintentional data disclosure, especially in regulated financial or internal research contexts where users may assume data remains local except for the mentioned SQLite backup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The alerting code transmits raw operational error details, exchange names, failure counts, and timestamps to an external Feishu webhook. Error strings can contain sensitive internal information such as URLs, stack fragments, credentials in exception messages, or environment-specific details, so forwarding them off-system increases information disclosure risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The code performs an external POST to a configurable webhook containing operational telemetry and error content. In a monitoring skill this transmission is expected, but it still creates a real data-exfiltration channel if the webhook is misconfigured, attacker-controlled, or if sensitive exception data is included in the payload.

Content

Scanner excerpt · main.py (reported line 192)May include surrounding context.

python
"text": f"🚨 IPO监控告警\n\n交易所: {exchange}\n连续失败: {failure_count} 次\n错误: {error}\n时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
                }
            }
            response = requests.post(alert_webhook, json=message, timeout=10)
            if response.status_code == 200:
                self.logger.info(f"告警发送成功: {exchange}")
            else:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The default request headers force Accept-Language to prefer zh-CN and Chinese (zh) ahead of English for all requests. This is a natural-language/locale policy issue because the skill imposes a specific locale preference by default, and the file does not show any user choice or region-specific justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This Python file performs remote page access via browser.action(action="open", url=url) and then extracts page content with browser evaluation calls, but the implementation only uses internal logging for failures and result counts. There is no confirmation prompt or explicit user-facing disclosure in the code comments/docstrings that the skill will connect to external websites and retrieve their contents.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This Python file contains user-facing natural-language descriptions entirely in Chinese and sets the default exchange parameter to the Chinese locale context "港股". Under the policy, forcing a specific language or locale without offering user choice or documenting a justified regional constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file’s natural-language docstrings and metadata are entirely in Chinese, and the constructor defaults the exchange label to a Chinese term. This creates a language/locale constraint without any visible opt-in, alternative locale handling, or documented region-specific justification, which matches the policy concern for forced language behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The module docstrings and method descriptions are entirely in Chinese, and the scraper's default exchange is hard-coded to '深交所'. This imposes a specific language/locale context without any visible opt-in or explanation that the skill is intentionally limited to a China-specific audience or workflow.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · storage/feishu_pusher.py (reported line 139)May include surrounding context.

python
}
        
        try:
            response = requests.post(url, json=payload, timeout=10)
            result = response.json()
            
            if result.get('code') == 0:

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains natural-language documentation entirely in Chinese (for example, the module docstring and class/method descriptions) with no indication that the skill is region-specific or that users may choose another language. That creates a locale-policy issue because the skill implicitly forces a specific language without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code file contains natural-language documentation entirely in Chinese, including the module docstring and class description, with no indication that language choice is optional or that the skill is intended only for a Chinese-speaking or region-specific context. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README describes local persistence to SQLite and logging to files without clearly warning users that fetched content and operational metadata will be written to disk. In shared or managed environments, undisclosed local storage can create retention, privacy, and forensic exposure risks, especially if file permissions, backup behavior, or cleanup are not documented.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

README 在 L949-L953 的开发任务中仍将 SQLiteStorage 和 main.py 标记为待实现,但前文 L152、L162、L193、L200 的主入口代码已经依赖 SQLiteStorage.load_all/save_all 并呈现为现成实现。该文档状态与代码展示相互矛盾,容易误导审计者对技能实际能力和成熟度的判断。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file’s human-facing natural language is entirely in Chinese, including section headers and operational comments, with no indication that other languages are supported or that this locale restriction is intentional. Under the policy rule for language/locale, this can be considered a forced locale choice without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level description and user-facing usage text are written only in Chinese, and additional runtime messages throughout the file also assume Chinese output. This imposes a specific language/locale without offering the user a choice or documenting it as a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · main.py (reported line 88)May include surrounding context.

python
# 配置日志
        logger = logging.getLogger('ipo_monitor')
        logger.setLevel(getattr(logging, self.config.log_level))
        
        # 文件处理器
        file_handler = logging.FileHandler(

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only, so builds may resolve to different versions over time and accidentally introduce vulnerable or incompatible releases. In a security-sensitive automation skill that likely performs network operations, this weakens supply-chain control and makes incident response and reproducibility harder.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
# IPO监控技能 V2

# Python依赖
requests>=2.28.0
urllib3>=1.26.0
beautifulsoup4>=4.11.0
pyyaml>=6.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

Requests has multiple known advisories, and because the manifest does not pin a version, it is impossible to verify whether deployments will avoid affected releases. In a skill likely intended to fetch IPO-related web content, this uncertainty increases exposure to HTTP client flaws and credential-handling issues if an unsafe version is resolved.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Using an unpinned urllib3 version allows the installed package to drift across environments and time, which can silently pull in a vulnerable release or behavior change. Because urllib3 is core HTTP infrastructure, supply-chain unpredictability can directly affect transport security and request handling.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
# Python依赖
requests>=2.28.0
urllib3>=1.26.0
beautifulsoup4>=4.11.0
pyyaml>=6.0