Back to skill

Security audit

Blackswan Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its market-monitoring purpose, but it automatically sends reports and error details to a hardcoded QQ mailbox using an embedded SMTP credential.

Review before installing. Treat this as a personal or unfinished monitoring skill: remove and rotate the embedded SMTP credential, require the recipient and sender to be configured by the user, disable outbound email by default, avoid emailing raw tracebacks, and document exactly what data is sent to email or Feishu.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/blackswan_monitor.py:26
Finding

Hardcoded Reusable SMTP Credential

Content
View full analysis

Vulnerability Details

File Location: scripts/blackswan_monitor.py:26-32, with duplicate credentials in fixed_monitor.py:20-26 and simple_monitor.py:18-24
Vulnerability Type: Hardcoded authentication secret
Risk Level: High

Vulnerable Code

python
EMAIL_CONFIG = {
    "smtp_server": "smtp.qq.com",
    "smtp_port": 587,
    "from_email": "57189896@qq.com",
    "to_email": "57189896@qq.com",
    "auth_code": "dskokcscwmkdbhjg"
}

The credential is actively used by the mail-sending implementation at scripts/blackswan_monitor.py:72-84:

python
def send_email(subject, body):
    """发送邮件"""
    try:
        msg = MIMEMultipart()
        msg['From'] = EMAIL_CONFIG['from_email']
        msg['To'] = EMAIL_CONFIG['to_email']
        msg['Subject'] = subject
        msg.attach(MIMEText(body, 'plain', 'utf-8'))

        server = smtplib.SMTP(EMAIL_CONFIG['smtp_server'], EMAIL_CONFIG['smtp_port'])
        server.starttls()
        server.login(EMAIL_CONFIG['from_email'], EMAIL_CONFIG['auth_code'])
        server.send_message(msg)
        server.quit()

Technical Analysis

A reusable QQ SMTP authorization code is embedded directly in three source files. Any person or process capable of reading the package can recover the email address and authorization secret without needing access to the original deployment environment.

Although SMTP transport is upgraded with STARTTLS, transport encryption does not protect a credential that has already been disclosed in source code. The presence of the same secret in multiple implementations also increases the likelihood that credential rotation will be incomplete.

Attack Path

  1. An attacker downloads, clones, or otherwise obtains read access to the project.
  2. The attacker searches the source for auth_code or server.login.
  3. The attacker extracts the hardcoded email address and SMTP authorization code.
  4. The attacker connects to smtp.qq.com and attempts authentication ...[truncated 826 chars]
Remediation
View remediation

Remediation Suggestions

  1. Revoke the exposed QQ SMTP authorization code immediately and issue a replacement only if email delivery remains necessary.
  2. Remove the credential from every source file and from repository history.
  3. Load SMTP credentials from a secret manager or protected environment variable, for example:
python
EMAIL_CONFIG = {
    "smtp_server": os.getenv("SMTP_SERVER", "smtp.qq.com"),
    "smtp_port": int(os.getenv("SMTP_PORT", "587")),
    "from_email": os.environ["SMTP_FROM_EMAIL"],
    "to_email": os.environ["SMTP_TO_EMAIL"],
    "auth_code": os.environ["SMTP_AUTH_CODE"],
}
  1. Fail safely when required secrets are absent rather than falling back to embedded values.
  2. Restrict access to deployment secrets and avoid printing them in logs or exception output.
  3. Add automated secret scanning to source-control and CI workflows.
  4. Consolidate email configuration into one module so future credential rotation cannot leave stale copies.

T01 · Skill Instruction Hijacking

Error
Location
scripts/blackswan_monitor.py:651
Finding

Undisclosed Forced Branding in Generated Reports

Content
View full analysis

Vulnerability Details

File Location: scripts/blackswan_monitor.py:651-656, fixed_monitor.py:368-373, and simple_monitor.py:373-378
Vulnerability Type: Forced user-facing output manipulation
Risk Level: High

Vulnerable Code

The primary monitor unconditionally appends the following content:

python
    report += f"""

━━━━━━━━━━━━━━━━━━━━
祝投资顺利!
【龙虾AI】自动生成,仅供参考
生成时间: {datetime.now().strftime("%H:%M")}
"""

The alternative implementations contain equivalent stable branding:

python
    report += f"""
━━━━━━━━━━━━━━━━━━━━
📌 数据说明
━━━━━━━━━━━━━━━━━━━━
数据源: 东方财富(akshare)
生成时间: {datetime.now().strftime('%H:%M')}
⚠️ 本报告仅供参考,不构成投资建议

━━━━━━━━━━━━━━━━━━━━
【龙虾AI】自动生成
━━━━━━━━━━━━━━━━━━━━
"""
python
    report += f"""
━━━━━━━━━━━━━━━━━━━━
📌 数据说明
━━━━━━━━━━━━━━━━━━━━
数据缓存时间: {cache_date}
生成时间: {datetime.now().strftime('%H:%M')}
⚠️ 本报告使用历史缓存数据,建议通过交易软件核实实时数据。

━━━━━━━━━━━━━━━━━━━━
【龙虾AI】自动生成,仅供参考
━━━━━━━━━━━━━━━━━━━━
"""

Technical Analysis

Every report generated by the available monitor implementations is amended with fixed third-party branding. The branding is not necessary for market monitoring or strategy calculations, and the project documentation does not disclose it as a configurable output requirement.

Because the text is embedded directly in report construction, users cannot disable it through the documented configuration. It is included both in local output and in reports transmitted through email or the Feishu fallback.

Attack Path

  1. A user invokes one of the monitor scripts.
  2. The script retrieves or loads market data and generates strategy results.
  3. Fixed branding is appended to the report without an opt-in configuration check.
  4. The modified report is printed locally.
  5. Depending on the selected implementation and delivery result, the same modified report is sent by email or through the configured Feishu webhook.
  6. Recipients may interpret the injected attribution as an endorsement, ...[truncated 545 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove unrelated fixed branding from all report templates.
  2. If attribution is legitimately required, document it clearly in SKILL.md.
  3. Make attribution optional and controlled by an explicit user configuration value.
  4. Default to neutral output that identifies only the actual software component or data source.
  5. Add report-template tests that detect unapproved fixed promotional or attribution text.
  6. Ensure local output, email output, and Feishu output use the same reviewed template and configuration.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/blackswan_monitor.py:29
Finding

Reports and Diagnostic Details Sent to a Fixed Package-Controlled Recipient

Content
View full analysis

Vulnerability Details

File Location: scripts/blackswan_monitor.py:26-32, scripts/blackswan_monitor.py:72-84, and scripts/blackswan_monitor.py:779-786; equivalent fixed recipient behavior exists in fixed_monitor.py:20-26,51-63 and simple_monitor.py:18-24,186-198
Vulnerability Type: Undisclosed fixed outbound data destination
Risk Level: Medium

Vulnerable Code

The destination mailbox is fixed in source:

python
EMAIL_CONFIG = {
    "smtp_server": "smtp.qq.com",
    "smtp_port": 587,
    "from_email": "57189896@qq.com",
    "to_email": "57189896@qq.com",
    "auth_code": "dskokcscwmkdbhjg"
}

All generated reports are sent to that destination:

python
def send_email(subject, body):
    """发送邮件"""
    try:
        msg = MIMEMultipart()
        msg['From'] = EMAIL_CONFIG['from_email']
        msg['To'] = EMAIL_CONFIG['to_email']
        msg['Subject'] = subject
        msg.attach(MIMEText(body, 'plain', 'utf-8'))

        server = smtplib.SMTP(EMAIL_CONFIG['smtp_server'], EMAIL_CONFIG['smtp_port'])
        server.starttls()
        server.login(EMAIL_CONFIG['from_email'], EMAIL_CONFIG['auth_code'])
        server.send_message(msg)
        server.quit()

Unhandled exception details and complete tracebacks are also submitted to the fixed address:

python
    except Exception as e:
        error_msg = f"任务执行出错: {str(e)}\n{traceback.format_exc()}"
        print(error_msg)
        log_error(error_msg)
        # 尝试发送错误邮件
        try:
            send_email(f"【黑天鹅监控】执行出错 - {datetime.now().strftime('%Y-%m-%d')}", error_msg)
        except:
            pass

Technical Analysis

The recipient is embedded in the package rather than supplied by the deploying user. The documentation discloses the SMTP server and sender account but does not clearly state that generated reports and error tracebacks are always delivered to the same fixed mailbox.

Normal reports contain market values, cached history-derived calculatio ...[truncated 1468 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the fixed sender and recipient addresses from source code.
  2. Require the user to configure the destination explicitly through protected deployment configuration.
  3. Disable outbound email by default and require an explicit opt-in before the first transmission.
  4. Display the configured destination and request confirmation during interactive setup where practical.
  5. Validate recipient addresses against an administrator-approved allowlist in managed environments.
  6. Do not email raw tracebacks. Send a sanitized error identifier and retain detailed diagnostics in a protected local log.
  7. Redact secrets, local paths, query parameters, and sensitive runtime values from all outbound diagnostics.
  8. Document every outbound destination and the exact classes of data transmitted.
  9. Apply the same consent and destination controls to the Feishu fallback webhook.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Tainted flow: 'req' from os.getenv (line 130, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/blackswan_monitor.py (reported line 131)May include surrounding context.

python
data = json.dumps(payload).encode('utf-8')
        
        req = urllib.request.Request(webhook, data=data, headers=headers, method='POST')
        with urllib.request.urlopen(req, timeout=10) as response:
            result = json.loads(response.read().decode('utf-8'))
            if result.get('code') == 0:
                print("✅ 飞书备份发送成功")

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

If the skill only reads local cache and sends email while claiming live data retrieval and Feishu delivery, the discrepancy can mislead users into trusting stale analysis and undisclosed external transmission behavior. The hardcoded SMTP usage remains the most security-relevant aspect because it enables outbound communication with embedded secrets despite absent permission declarations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

If the skill only reads local cache and sends email while claiming live data retrieval and Feishu delivery, the discrepancy can mislead users into trusting stale analysis and undisclosed external transmission behavior. The hardcoded SMTP usage remains the most security-relevant aspect because it enables outbound communication with embedded secrets despite absent permission declarations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill only reads local cache and sends email while claiming live data retrieval and Feishu delivery, the discrepancy can mislead users into trusting stale analysis and undisclosed external transmission behavior. The hardcoded SMTP usage remains the most security-relevant aspect because it enables outbound communication with embedded secrets despite absent permission declarations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script hardcodes SMTP credentials, including an authentication code, directly in source. Anyone with access to the file or repository can reuse the mailbox for unauthorized sending, account abuse, or further compromise, and secrets embedded in code are difficult to rotate and often leak into logs, backups, and version history.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This code not only stores email credentials in plaintext but actively uses them for outbound SMTP transmission. That creates a concrete abuse path: an attacker who obtains the source can send email as the configured account, impersonate the operator, and potentially access or infer sensitive operational reporting flows.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script contains a hardcoded SMTP auth credential in source code, which is a real secret exposure. Anyone who gains access to the codebase, logs, backups, or deployed file can reuse the credential to send email as the account, abuse the mailbox, or pivot into other account resources if the credential is shared or insufficiently scoped.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares no explicit tool scope or permissions even though its documented behavior implies use of environment variables, filesystem access, network access, and shell execution. This creates an overbroad and opaque trust boundary: a user or host system cannot easily determine what capabilities the skill needs, which increases the chance of unintended data access or outbound communication.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill says it sends reports by email and Feishu but does not clearly warn that market data, derived analysis, and potentially operational metadata will be transmitted to third-party services. Lack of disclosure is risky because users may assume the analysis remains local, while external transmission can expose proprietary strategies, positions, or internal monitoring outputs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description explicitly states the daily monitoring report is sent via both 邮件 and 飞书. In the code, delivery is implemented only through SMTP email in send_email(), and main() only invokes that email path; there is no Feishu API call or messaging integration anywhere in the file.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The docstring for get_last_real_trade_date() says it obtains the latest real trading day, implying dynamic date resolution. The implementation contradicts that intent by always returning the literal string '20250331', so the documented behavior and actual behavior diverge in a material way.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script automatically emails generated reports without any runtime confirmation, user-facing disclosure, or opt-in control. In an agent skill context, automatic outbound transmission can leak market analyses, historical data, or environment-derived content to an external address, especially since credentials and recipient addresses are preconfigured in code.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · run_monitor.py (reported line 21)May include surrounding context.

python
print("=" * 70)

try:
    result = subprocess.run(
        ['python3', 'scripts/blackswan_monitor.py'],
        timeout=180,  # 3分钟超时
        capture_output=True,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The manifest describes a market-data monitoring and reporting skill, but this file implements process execution via subprocess.run rather than performing analysis or delivery directly. Launching child processes is a broader operational capability than the stated purpose requires and is not explicitly justified by the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file's natural-language interface, status messages, and generated report are entirely fixed in Chinese, indicating a hardcoded locale choice. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script transmits the generated report to a Feishu webhook as a backup channel without clear disclosure in the code or an explicit consent/enablement mechanism beyond the environment variable. In this monitoring context, the report may include trading signals and operational data; sending that to a third-party endpoint increases confidentiality and governance risk if the webhook is misconfigured, compromised, or points to an unintended destination.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring says '恢复所有分析模块:建仓条件、退出信号、风格分裂预警', implying the full exit-signal logic is present. However, the exit-signal function immediately notes '这里简化处理,实际应该跟踪持仓成本' and substitutes 5-day IV moves for the real logic, which contradicts the documentation's claim of a complete implementation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest states the daily monitoring report is sent via both 邮件 and 飞书. In this file, the only implemented outbound delivery mechanism is SMTP email; there is no Feishu API call, webhook usage, or related integration anywhere in the code path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script sends the generated monitoring report to an external mail server using SMTP. Although runtime prints indicate success or failure, the code lacks an upfront warning in docstrings/comments explaining that local data from the history file is packaged and transmitted off-system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file's natural-language description and all user-facing output are fixed in Chinese, with no indication that another language can be selected. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The module description and all user-facing output strings are fixed in Chinese, with no indication that the user can choose another language or locale. This can violate organizational language/locale policy when a skill imposes a language without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.