Back to skill

Security audit

Daily Morning Greetings

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its optional Weixin delivery can automatically send messages to broadly accepted webhook URLs and deserves review before installation.

Install only if you are comfortable with a Chinese morning-greeting skill that can use live weather services, create OpenClaw cron schedules when asked, and optionally duplicate messages to a detected Weixin bot. Review any WEIXIN/WECHAT webhook environment variables and OpenClaw config first, because a non-Weixin URL there could receive the generated greeting or be contacted from your machine.

Vulnerability Patterns
  • 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
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dispatch_morning_greeting.py:107
Finding

Unrestricted webhook destination permits SSRF and unintended message disclosure

Content
View full analysis

Vulnerability Details

File Location: scripts/dispatch_morning_greeting.py:107-110, 140-148, 195-211, 238-253, 323-333
Vulnerability Type: Server-Side Request Forgery through insufficient webhook validation
Risk Level: Medium

Vulnerable Code

python
def build_weixin_webhook_from_key(key):
    normalized = normalize_text(key)
    if not normalized:
        return None
    if normalized.startswith(("http://", "https://")):
        return normalized
    encoded = urllib.parse.quote(normalized, safe="")
    return f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={encoded}"
python
def looks_like_webhook_url(value):
    normalized = normalize_text(value)
    if not normalized:
        return False
    return normalized.startswith(("http://", "https://"))
python
def detect_weixin_from_env():
    for key in WEIXIN_ENV_WEBHOOKS:
        value = normalize_text(os.environ.get(key))
        if value:
            webhook = build_weixin_webhook_from_key(value)
            if webhook:
                return {
                    "source": f"env:{key}",
                    "webhook_url": webhook,
                }
    for key in WEIXIN_ENV_KEYS:
        value = normalize_text(os.environ.get(key))
        if value:
            webhook = build_weixin_webhook_from_key(value)
            if webhook:
                return {
                    "source": f"env:{key}",
                    "webhook_url": webhook,
                }
    return None
python
if normalized_value:
    if is_weixin_webhook_url(normalized_value):
        return build_weixin_webhook_from_key(normalized_value)
    if normalized_key in LIKELY_WEBHOOK_FIELDS:
        if "webhook" in normalized_key and looks_like_weixin_key(normalized_value):
            return build_weixin_webhook_from_key(normalized_value)
    if normalized_key in LIKELY_KEY_FIELDS and looks_l
...[truncated 4312 chars]
Remediation
View remediation

Remediation Suggestions

  1. Enforce an exact destination allowlist immediately before sending:

    • Require the https scheme.
    • Require the exact hostname qyapi.weixin.qq.com.
    • Require the exact path /cgi-bin/webhook/send.
    • Reject user information, fragments, non-default ports, and unexpected query parameters.
    • Require exactly one valid key parameter.
  2. Do not accept complete URLs from variables intended to contain webhook keys. Treat key variables strictly as opaque keys and construct the official URL internally.

  3. If full webhook URL variables must remain supported, validate them with a dedicated function and reject all non-Weixin hosts rather than merely checking for an HTTP or HTTPS prefix.

  4. Disable redirects or validate every redirect destination against the same allowlist. A validated initial URL must not be allowed to redirect to an internal or unapproved host.

  5. Resolve the destination and reject loopback, private, link-local, multicast, reserved, and metadata-service addresses. Repeat validation after DNS resolution and for every redirect to reduce DNS rebinding risk.

  6. Remove generic url from LIKELY_WEBHOOK_FIELDS, or only inspect explicit webhook fields within a narrowly defined Weixin bot configuration schema. Avoid recursive interpretation of loosely related configuration values.

  7. Reject cleartext HTTP entirely to protect webhook keys and message content in transit.

  8. Add tests covering attacker-controlled public hosts, loopback addresses, private network ranges, IPv6 local addresses, encoded hostnames, user-information syntax, nonstandard ports, redirects, and malformed or duplicate key parameters.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill is presented as a morning-greeting generator but its instructions also authorize cron creation, route binding, failure alerts, and cross-channel delivery behavior. This mismatch can mislead users and reviewers about the real operational scope, increasing the chance that persistent tasks or message delivery changes are performed without informed consent or adequate scrutiny.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 221)May include surrounding context.

md
6. cron 不要在触发时重新读完整 `SKILL.md`;必须改用内联轻量 payload。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 241)May include surrounding context.

md
6. cron 不要在触发时重新读完整 `SKILL.md`;必须改用内联轻量 payload。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 324)May include surrounding context.

md
6. cron 不要在触发时重新读完整 `SKILL.md`;必须改用内联轻量 payload。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 371)May include surrounding context.

md
6. cron 不要在触发时重新读完整 `SKILL.md`;必须改用内联轻量 payload。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to use shell commands, read environment/configuration, access files, and make network requests, yet it declares no explicit tool scope or permissions boundary. That creates an overprivileged execution surface where a greeting skill can unexpectedly perform scheduling, route changes, and external transmission, making misuse or accidental abuse harder to constrain and audit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill enables active cron scheduling and delivery-route binding across chat channels, but the top-level description does not clearly warn that it may create persistent automations or change where messages are sent. In context, this is more dangerous because the skill is not just formatting text; it can trigger ongoing outbound messaging in the background.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction requires all user-visible wording to use the Chinese term 早安问候, and later writing-style rules require colloquial Chinese output. This forces a specific language/locale behavior without indicating user opt-in or offering an alternative, which can violate language-choice policy for general-purpose skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The Weixin bot fanout section describes automatic transmission of message content to an external webhook when configuration is detected, but it does not require explicit user disclosure or consent at send time. Because webhook endpoints are third-party delivery channels, silent fanout can leak message content, routing metadata, or user expectations of channel confinement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON file contains all user-facing content exclusively in Chinese, including roles, quotes, and blessings, with no indication that the skill is region-specific or that users can choose another language. Under the policy rule, hard-coding a specific language without opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file consistently forces Chinese-language output, including city labels, weekday strings, weather descriptions, and rendered greeting text, with no apparent user opt-in or locale selection mechanism. That is a natural-language policy concern when a skill mandates a specific language rather than allowing user choice or clearly documenting a justified locale restriction.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/build_daily_context.py (reported line 582)May include surrounding context.

python
"forecast_days": 1,
        }
    )
    payload = fetch_json(f"https://api.open-meteo.com/v1/forecast?{query}")
    current = payload.get("current") or {}
    daily = payload.get("daily") or {}
    code = as_int(current.get("weather_code"))

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 · scripts/dispatch_morning_greeting.py (reported line 184)May include surrounding context.

python
if args.scope_key:
        cmd.extend(["--scope-key", args.scope_key])

    completed = subprocess.run(
        cmd,
        capture_output=True,
        text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill can automatically exfiltrate generated message content to an external Weixin webhook by discovering credentials from environment variables or OpenClaw configuration, without an explicit confirmation step in this code path. In a chat-agent skill context, this is more dangerous because a user request to generate or resend a greeting can trigger outbound delivery across channels, potentially causing unintended disclosure or cross-channel posting.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The package description states 'Shanghai default', which indicates the skill defaults to a specific city/locale. Under the policy, forcing a locale without offering a user choice or documenting opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script sends the user-supplied or environment-derived city value to wttr.in as part of an HTTP request, but there is no print/log message, confirmation, or comment/docstring warning that location data is sent to a third-party service. Under the code-file criteria, network calls that transmit user or system data should have some form of user disclosure unless clearly documented elsewhere in the skill description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script queries Open-Meteo's geocoding API with the supplied city name and later uses the resolved coordinates/timezone for forecast requests, but the code does not visibly warn the user that these location details are sent off-box. This is a semantic safety transparency issue because location information can be privacy-relevant even if not highly sensitive.

Content

No source excerpt is available for this finding.