Back to skill

Security audit

Wework Financial Daily

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent reporting goal, but it embeds credentials, publishes reports through a hard-coded public MinIO setup, and recommends elevated scheduled execution.

Review before installing. Do not run this as administrator or with highest privileges. Treat the embedded WeChat and MinIO values as exposed secrets that should be revoked or rotated. Avoid using the public MinIO upload path unless you intend reports to be externally accessible, and prefer private storage with short-lived links. Treat the generated market data as simulated unless the code is changed to use a real market-data source.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/cron-setup.md:31
Finding
Recurring Scheduled Task Runs with Unnecessary Highest Privileges<![CDATA[ ## Vulnerability Details **File Location**: `references/cron-setup.md:31-41`; related instructions in `README-定时任务配置.md:33-52` and `SKILL.md:52-62` **Vulnerability Type**: Privileged scheduled-task persistence **Risk Level**: High ### Vulnerable Code ```powershell # Create task schtasks /Create /TN "每日金融课件推送" /TR "python.exe C:\Users\wwwir\.openclaw\workspace\skills\wework-financial-daily\scripts\generate_and_send.py" /SC DAILY /ST 09:00 /RL HIGHEST /F # Query task schtasks /Query /TN "每日金融课件推送" # Delete task schtasks /Delete /TN "每日金融课件推送" /F ``` The graphical setup instructions additionally tell the user to: ```text Run whether the user is logged on or not Run with highest privileges ``` ### Technical Analysis A daily scheduled task is consistent with the Skill's declared automatic-reporting functionality. However, the task is explicitly configured with `/RL HIGHEST`, and the documentation repeatedly directs the user to create it as an administrator. Generating an HTML report, writing it to the user's desktop, uploading it, and making outbound HTTP requests do not inherently require administrator rights. The highest-privilege configuration therefore violates least-privilege principles. The risk is amplified because the scheduled action invokes `python.exe` and a script under a user workspace path. If an unprivileged user or compromised process can replace the script, modify imported modules, influence Python resolution, or change the interpreter found through `PATH`, the scheduled task becomes a recurring elevated-code execution mechanism. Although the persistence is disclosed rather than covert, the privilege level exceeds the minimum necessary for the declared functionality. ### Attack Path 1. The user follows the documentation and creates the task from an administrator session. 2. Windows registers the task to run daily with the highest available privileges. 3. An attacker gains write access to the Skill script, its directory, an impo ...[truncated 890 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `/RL HIGHEST` and create the task under a dedicated, unprivileged account. 2. Do not require administrator execution unless a separately documented operation demonstrably needs it. 3. Configure the task with an absolute, trusted Python interpreter path rather than `python.exe`. 4. Store the Skill in a directory writable only by the task owner and administrators. 5. Use a dedicated virtual environment whose packages and entry points cannot be modified by unrelated users. 6. Restrict the task to the minimum required network and filesystem permissions. 7. Make scheduled-task creation an explicit, opt-in setup step and clearly document how to disable and remove it. 8. Consider using OpenClaw's user-level scheduler instead of an operating-system task with elevated privileges. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_and_send.py:24
Finding
Hard-Coded API and Object-Storage Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_and_send.py:24-36` **Vulnerability Type**: Hard-coded secrets and authentication token exposure **Risk Level**: Critical ### Vulnerable Code ```python X_TOKEN = "eyJhbGciOiJI" TO_USER = "18018517752" API_URL = f"https://kd.chatedu.jiaxutech.com/service/v1/wx-work/send?x-token={X_TOKEN}" HEADERS = {"Content-Type": "application/json"} MINIO_ENDPOINT = "1.15.115.88:9000" MINIO_ACCESS_KEY = "gWDVHdO8sAba6LTNSLCd" MINIO_SECRET_KEY = "wi2ZRu3ewRJaOqdZKKDW90l9SPjNYwEqiitHKK1g" MINIO_SECURE = False MINIO_BUCKET = "financereports" MINIO_PUBLIC_URL = "http://1.15.115.88:9090" ``` ### Technical Analysis The source contains an API token, a recipient identifier, and a MinIO access-key pair. The MinIO values have the structure of deployable credentials and must be treated as compromised even though their current validity was not tested during this static audit. The documentation says that WeCom settings are supplied through `WEWORK_X_TOKEN` and `WEWORK_TO_USER` environment variables, but the implementation does not read those variables. Instead, it always uses the embedded values. The API token is interpolated into a query parameter. Query-string credentials are more likely to be exposed through proxy logs, server access logs, monitoring systems, browser or debugging history, and error reports than credentials carried in a protected authorization header. The hard-coded `TO_USER` value is not included in the constructed outbound payload, which also makes the documented recipient configuration ineffective. ### Attack Path 1. An attacker obtains a copy of the Skill package, source repository, build artifact, backup, or endpoint filesystem. 2. The attacker reads the embedded API token and MinIO access-key pair without needing to compromise a separate secret store. 3. The attacker attempts authentication directly against the configured API and MinIO endpoint. 4. If the credentials remain active, the ...[truncated 838 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the exposed API token, MinIO access key, and MinIO secret key. 2. Remove all credentials and recipient identifiers from source control and distributed artifacts. 3. Read configuration from environment variables or a protected operating-system secret store: ```python X_TOKEN = os.environ["WEWORK_X_TOKEN"] TO_USER = os.environ["WEWORK_TO_USER"] MINIO_ACCESS_KEY = os.environ["MINIO_ACCESS_KEY"] MINIO_SECRET_KEY = os.environ["MINIO_SECRET_KEY"] ``` 4. Pass API authentication through an authorization header rather than a URL query parameter. 5. Ensure secret values are never printed, included in exception output, or recorded in task logs. 6. Grant the storage identity access only to the required bucket and object prefix. It should not be permitted to alter bucket policies. 7. Use separate credentials for development and production, with expiration and regular rotation. 8. Add automated secret scanning to repository and release pipelines. 9. Purge leaked values from repository history where feasible, while recognizing that history rewriting does not replace credential rotation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_and_send.py:47
Finding
Reports Are Uploaded over Plaintext and the Entire Bucket Is Made Public<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_and_send.py:47-94` **Vulnerability Type**: Insecure transport and unsafe bucket-wide access-control modification **Risk Level**: Critical ### Vulnerable Code ```python client = Minio( MINIO_ENDPOINT, access_key=MINIO_ACCESS_KEY, secret_key=MINIO_SECRET_KEY, secure=MINIO_SECURE ) if not client.bucket_exists(bucket_name): client.make_bucket(bucket_name) policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"AWS": "*"}, "Action": ["s3:GetObject"], "Resource": [f"arn:aws:s3:::{bucket_name}/*"] } ] } client.set_bucket_policy(bucket_name, json.dumps(policy)) report_date = time.strftime("%Y-%m-%d") safe_file_name = f"finance-report-{report_date}.html" content_type = "text/html; charset=utf-8" client.fput_object( bucket_name=bucket_name, object_name=safe_file_name, file_path=file_path, content_type=content_type ) public_url = f"http://{MINIO_ENDPOINT}/{bucket_name}/{safe_file_name}" ``` The corresponding configuration is: ```python MINIO_ENDPOINT = "1.15.115.88:9000" MINIO_SECURE = False MINIO_BUCKET = "financereports" ``` ### Technical Analysis Setting `secure=False` instructs the MinIO client to communicate with the object-storage endpoint without TLS. Authentication material and report content are therefore not protected by transport encryption against network observation or modification. On every run, the script also calls `set_bucket_policy` with an anonymous principal and `s3:GetObject` access to every object in the bucket. This is not limited to the newly generated report. Existing and future objects under `financereports/*` become anonymously readable if the policy call succeeds. Changing a bucket-wide policy is materially broader than uploading one report. A safer design would keep the bucket private and generate a short-lived presigned ...[truncated 1584 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable external upload by default and require explicit user opt-in. 2. Replace the hard-coded endpoint with a user-configured, approved storage destination. 3. Require HTTPS/TLS and validate the server certificate: ```python client = Minio( endpoint, access_key=access_key, secret_key=secret_key, secure=True, ) ``` 4. Remove automatic `set_bucket_policy` calls entirely. 5. Keep the bucket private and issue a short-lived presigned URL for only the newly uploaded object. 6. Use an unpredictable object identifier rather than a date-only filename if URLs may be distributed externally. 7. Apply least-privilege storage credentials that can upload only to a dedicated prefix and cannot create buckets or modify policies. 8. Obtain explicit user approval before transmitting locally generated files to an external service. 9. Document the destination, retention period, access model, and deletion procedure. 10. Audit the existing bucket immediately and restore a private policy. Review access logs to determine whether objects were retrieved anonymously. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/generate_and_send.py:515
Finding
Unpinned Runtime Package Installation from a Third-Party Mirror<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_and_send.py:515-522` **Vulnerability Type**: Unsafe dependency installation and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```python def main(): required_pkgs = ["requests", "pandas", "matplotlib", "numpy", "minio"] for pkg in required_pkgs: try: __import__(pkg) except ImportError: print(f"Installing {pkg}...") os.system(f"pip install {pkg} -i https://pypi.tuna.tsinghua.edu.cn/simple") ``` ### Technical Analysis The script attempts to install missing packages dynamically from a third-party package index. It does not pin versions, verify package hashes, use a lockfile, invoke a dedicated virtual environment, or request confirmation before installation. A package index compromise, malicious upstream release, dependency takeover, or resolution change could cause different code to be installed on different runs. Python packages can execute installation or build logic during installation and will later execute arbitrary code when imported. The package names are currently selected from a hard-coded list, so this specific command is not directly vulnerable to user-controlled shell injection. The principal issue is supply-chain integrity. The script imports the same packages at module load time before `main()` executes. Consequently, in the current implementation a genuinely missing top-level package will usually terminate execution before the recovery loop is reached. This limits immediate exploitability of the automatic installer, but it also shows that dependency handling is both unsafe and unreliable. The dangerous installation pattern would become active if imports were reorganized or if the loop were reused independently. The risk becomes more serious when combined with the documentation's recommendation to run the script from a highest-privilege scheduled task. ### Attack Path 1. The installer loop is ...[truncated 1176 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all package installation behavior from the runtime script. 2. Declare dependencies in a reviewed requirements or lock file with exact versions. 3. Require package hashes, for example through `pip install --require-hashes`. 4. Install dependencies during an explicit setup phase rather than from a scheduled production task. 5. Use a dedicated virtual environment owned by the unprivileged task account. 6. Use an organization-approved package index and retain provenance information for downloaded artifacts. 7. Scan direct and transitive dependencies for known vulnerabilities before release. 8. Avoid `os.system`; if a setup utility must invoke pip, use the current interpreter and an argument array: ```python subprocess.run( [sys.executable, "-m", "pip", "install", "--require-hashes", "-r", "requirements.txt"], check=True, ) ``` 9. Ensure scheduled execution fails safely with a clear dependency error rather than modifying the host environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose materially differs from the detected behavior: the skill reportedly uploads reports to MinIO, makes them publicly accessible, changes bucket policy, uses hardcoded credentials instead of environment variables, and presents simulated data as if it were current market data. This combination is dangerous because it conceals sensitive data exposure, weakens credential hygiene, and misleads users about both where their data goes and the authenticity of the generated financial content.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
schtasks /Query /TN "每日金融课件推送"

# 删除任务
schtasks /Delete /TN "每日金融课件推送" /F
```

## OpenClaw Cron 配置
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
schtasks /Query /TN "每日金融课件推送"

# 删除任务
schtasks /Delete /TN "每日金融课件推送" /F
```

## OpenClaw Cron 配置
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The code hardcodes an API token, recipient identifier, and MinIO access credentials directly in the script despite claiming environment-variable-based configuration. Embedded secrets are highly dangerous because anyone with file access can reuse them to send messages, access storage, or pivot into related infrastructure, and the discrepancy suggests deceptive or careless handling of credentials.

Missing User Warnings

High
Confidence
98% confidence
Finding
The script uploads the generated report to MinIO and sets the entire bucket policy to public read without explicit user warning. This creates direct confidentiality and data-governance risk because reports become externally accessible, and bucket-wide public exposure may unintentionally reveal other objects in the same bucket as well.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill claims to generate current financial data but actually fabricates pseudo-random prices and charts. In a financial-reporting context, this is dangerous because recipients may trust and act on false data, making the deception materially riskier than a harmless demo mismatch.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
Executing package installation during normal script runtime is outside the stated business purpose and introduces avoidable code execution and supply-chain exposure. A reporting tool should not silently alter the host environment or fetch executable content from external repositories during operation.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
__import__(pkg)
        except ImportError:
            print(f"📌 正在安装 {pkg} 库...")
            os.system(f"pip install {pkg} -i https://pypi.tuna.tsinghua.edu.cn/simple")
    
    # 执行全流程
    try:
Confidence
91% confidence
Finding
The script executes a shell command at runtime to install packages with os.system, which is an unnecessary command-execution primitive for a reporting skill. Even though pkg is from a fixed list, this still causes uncontrolled system modification, depends on external package infrastructure at execution time, and expands the attack surface through shell invocation and supply-chain risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The guide tells users to store a corporate WeCom token in a system environment variable without noting that the token is a sensitive credential. System-wide variables may be visible to administrative users, inherited by child processes, and persist longer than necessary, increasing exposure if the host is shared or compromised.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The README instructs users to create and run a scheduled task with administrator rights and 'highest privileges' even though the described function is only generating reports and sending WeCom messages. This unnecessarily expands the blast radius: if the script, its dependencies, or the task configuration are modified, they would execute with elevated privileges and persistence.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instructions tell users to run an administrator PowerShell setup script that creates a persistent scheduled task, but they do not explain the security implications of elevation and persistence. Users may grant broad privileges without understanding that any later tampering with the script path or dependencies could result in privileged recurring execution.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
Suggesting users hardcode the WeCom token directly into the Python script weakens secret handling by moving credentials into source files that may be backed up, shared, version-controlled, or exposed to other local users. This increases the chance of credential leakage and undermines the stated environment-variable-based design.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Recommending direct hardcoding of configuration in the Python script without warning against embedding credentials encourages insecure secret storage practices. If the script is copied, logged, synced, or committed to a repository, the token could be exposed and abused to send unauthorized corporate messages.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises behavior that writes files, uses the network, and invokes scripts, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because users and the platform cannot easily evaluate or constrain what the skill is allowed to do, especially given that it performs scheduled execution, local file writes, and external messaging.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill description does not prominently warn users that it will automatically send content to Enterprise WeChat, save files to the local desktop, and support scheduled execution. This is dangerous because users may trigger persistent side effects or outbound communications without fully informed consent, especially in an automation context.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs users to place the Enterprise WeChat token directly into source code, which creates a high risk of accidental credential leakage through version control, backups, screenshots, or local sharing. Because the token enables outbound messaging/API access, exposure could allow unauthorized use of the messaging integration.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instructions recommend running the scheduled task with highest privileges and 'whether user is logged in or not' without explaining why elevation is needed. If the Python script, its dependencies, or the workspace path are modified, the task can become a privileged execution path and increase the blast radius of compromise.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The guide tells users to place `WEWORK_X_TOKEN` directly into YAML and a `.bat` file, which creates plaintext credential exposure risk through local files, backups, screenshots, source control, and task configuration sharing. In the context of an automation skill that sends data to Enterprise WeChat, this can allow unauthorized use of the bot token if the machine or workspace is accessed by another user or process.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module docstring states that the script generates current data, but the implementation uses simulated values throughout. This mismatch is security-relevant because it conceals actual behavior and can mislead operators or reviewers about the trustworthiness of generated reports.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script's user-facing strings, generated HTML, and markdown output are entirely in Chinese, and the HTML explicitly sets lang="zh-CN". There is no indication that the skill is region-specific or that users can opt into another language, which conflicts with the policy against forcing a language or locale without opt-in.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The script does more than its stated local-save and WeChat-push purpose by uploading reports to MinIO and creating a publicly accessible link. Hidden external publication materially increases exposure because generated content is transmitted off-host and made accessible to anyone with the URL, without matching the declared behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script persistently writes an HTML file to the user's Desktop without prior confirmation. While not inherently malicious, unannounced file writes can violate user expectations, create unwanted artifacts, and are more concerning here because the generated file contains financial content later shared externally.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script transmits report content to an external enterprise messaging API without an upfront warning or consent step. In this skill context, external messaging is expected at a high level, but the lack of explicit notice still matters because content and metadata leave the local environment automatically.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
required_pkgs = ["requests", "pandas", "matplotlib", "numpy", "minio"]
    for pkg in required_pkgs:
        try:
            __import__(pkg)
        except ImportError:
            print(f"📌 正在安装 {pkg} 库...")
            os.system(f"pip install {pkg} -i https://pypi.tuna.tsinghua.edu.cn/simple")
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The markdown provides `schtasks /Delete ... /F`, where `/F` suppresses confirmation and permanently deletes the task. For markdown guidance, destructive operations should carry a brief warning so users understand the action is irreversible unless they recreate the task.

Static analysis

No suspicious patterns detected.