Back to skill

Security audit

OpenLX 微信公众号免白名单发布

Security checks across malware telemetry and agentic risk

Overview

The skill mostly matches its WeChat gateway purpose, but its credential handling and update installer create review-worthy risk before installation.

Review this before installing. It is not clearly malicious, but installation gives the package authority to modify local agent skill directories, and the update chain lacks signed metadata. Use only with a limited OpenLX API key, avoid unattended update flags unless you intend replacement, and prefer waiting for redirect restrictions and signed or host-pinned update metadata.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gateway.py:33
Finding
API Credential Disclosure Through Cross-Origin HTTP Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gateway.py`, lines 33-39 **Vulnerability Type**: Cross-origin credential forwarding through unrestricted redirects **Risk Level**: High ### Vulnerable Code ```python key=os.environ.get('OPENLX_WEIXIN_API_KEY') if not key: raise ValueError('OPENLX_ACCESS_CREDENTIAL_MISSING') headers={'Content-Type':'application/json','x-api-key':key} # Gateway does not guarantee idempotency-key deduplication. Never blind retry a write. req=urllib.request.Request('https://wx.openlx.cn/v2/proxy/'+endpoint,data=json.dumps(payload,ensure_ascii=False).encode(),headers=headers) try: with urllib.request.urlopen(req,timeout=180) as r: return json.load(r) ``` ### Technical Analysis The request places the sensitive `OPENLX_WEIXIN_API_KEY` value in the `x-api-key` header and passes the request to `urllib.request.urlopen`. Python's standard URL-opening behavior follows HTTP redirects by default. The implementation neither disables redirects nor verifies that the final response remains on the exact `https://wx.openlx.cn` origin. During redirect processing, custom request headers may be retained. Therefore, a redirect to a different HTTPS origin can result in the API-key header being forwarded to that origin. Using HTTPS only protects the connection to the selected destination. It does not prevent disclosure when the destination itself changes to an attacker-controlled HTTPS server. Exploitation requires the OpenLX gateway, its routing infrastructure, or an upstream response path to return a malicious or compromised redirect. ### Attack Path 1. A user configures a valid `OPENLX_WEIXIN_API_KEY` and invokes `scripts/gateway.py`. 2. The client sends an authenticated request to `https://wx.openlx.cn/v2/proxy/...`. 3. The gateway or compromised upstream infrastructure returns an HTTP redirect to an attacker-controlled HTTPS origin. 4. `urllib.request.urlopen` follows the redirect because redirects are enabled by default. 5. ...[truncated 983 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable automatic redirects for authenticated gateway requests. 2. If redirects are operationally required, implement a custom redirect handler that: - Accepts only the `https` scheme. - Accepts only the exact hostname `wx.openlx.cn`. - Accepts only the expected HTTPS port. - Rejects redirects involving user information, unexpected ports, or alternate subdomains. 3. Remove `x-api-key` before constructing any redirected request and restore it only after confirming that the destination has the same trusted origin. 4. Validate the final response URL before reading or trusting the response. 5. Prefer rejecting all cross-origin redirects rather than relying on header-removal behavior. 6. Add automated tests covering 301, 302, 303, 307, and 308 responses to same-origin and cross-origin destinations. 7. Rotate potentially exposed API keys if logs indicate that authenticated requests previously encountered unexpected redirects. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/manager.py:18
Finding
Unsigned Update Manifest Can Select Arbitrary HTTPS Package Sources<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manager.py`, lines 18-27 and 42-48 **Vulnerability Type**: Unauthenticated update metadata and insufficient package-origin validation **Risk Level**: Medium ### Vulnerable Code ```python def fetch(url,timeout=15): if not url.startswith('https://'): raise ValueError('HTTPS_REQUIRED') with urllib.request.urlopen(urllib.request.Request(url,headers={'User-Agent':ID+'/0.1.1'}),timeout=timeout) as r: if not r.url.startswith('https://'): raise ValueError('HTTPS_REQUIRED') return r.read(30*1024*1024+1) def manifest(a): if a.manifest_file: return read(Path(a.manifest_file)) url=GITHUB+'v'+a.version+'/release-manifest.json' if a.source=='github' and a.version else OFFICIAL m=json.loads(fetch(url,4 if a.command=='check-update' else 15)) if m.get('skill_id')!=ID: raise ValueError('MANIFEST_ID_MISMATCH') return m ``` ```python def install(a,agent,base,state,dest): m=manifest(a); v=a.version or m['latest']['beta'] if not v or not v.startswith('0.'): raise ValueError('BETA_VERSION_REQUIRED') entry=m['versions'][v]; f=entry['files'][0] if m['skill_id']!=ID or not entry['pre_release']: raise ValueError('MANIFEST_INVALID') b=Path(a.package_file).read_bytes() if a.package_file else fetch(f['github_url'] if a.source=='github' else f['official_mirror_url']) if len(b)!=f['size'] or digest(b)!=f['sha256']: raise ValueError('PACKAGE_HASH_MISMATCH') ``` ### Technical Analysis The update manager accepts package URLs from a remotely retrieved manifest. The `fetch` function verifies only that the original and final URLs begin with `https://`; it does not require the package or redirect destination to belong to the documented OpenLX or GitHub release origins. Although downloaded packages are checked with SHA-256, the expected size and digest are supplied by the same unsigned manifest that supplies the package URL. If that manifest is compromised, an attacker can provide all three mutually consistent val ...[truncated 2444 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Authenticate release manifests using a digital signature verified against a public key embedded in the audited installer. 2. Keep package hashes in signed metadata so that compromising the package host alone cannot authorize a malicious replacement. 3. Allowlist exact package origins: - Official packages should use the exact approved OpenLX hostname. - GitHub packages should use expected GitHub release hosts and repository paths. 4. Validate URL components with a URL parser rather than a string-prefix test. Enforce: - Scheme equal to `https`. - Exact approved hostname. - Expected port. - Approved path prefix. - No embedded user information. 5. Validate every redirect destination against the same allowlist, or disable redirects entirely. 6. Pin the expected package filename and reject unexpected or multiple file entries in manifest metadata. 7. Consider a threshold-signature or trusted update framework such as TUF for rollback protection, metadata expiration, key rotation, and separation of repository roles. 8. Record and enforce a trusted version sequence to prevent downgrade attacks. 9. Preserve the existing archive traversal, symbolic-link, size, and digest checks as defense-in-depth measures. ]]>

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documentation directs use of environment variables, local files, shell execution, and a networked gateway, yet no explicit permissions are declared. This creates a transparency and consent problem: an agent or user may authorize or run the skill without understanding that it can access secrets, read/write local state, and make outbound requests.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims a narrow operational purpose around WeChat authorization and content routing, but its referenced maintenance flow adds software installation, remote updates, rollback, uninstall, integrity checks, and agent-directory modification. That mismatch is dangerous because users may trust it as a publishing helper while it also changes local installations and fetches remote packages, increasing supply-chain and persistence risk.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
This file is a full installer/update manager that downloads release manifests and packages, writes into local agent skill directories, and maintains backups/state, which is materially unrelated to the declared WeChat authorization and content-routing purpose. That mismatch is dangerous because users or hosting platforms may grant trust based on the advertised business function while the code performs privileged local software deployment actions instead.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The script modifies local agent directories under the user's home directory, replaces installed skill content, and persists state/backups even though the stated skill purpose does not justify filesystem management capabilities. In the context of a skill that claims to handle WeChat authorization/routing, this expands the attack surface and can be abused to plant or replace local skill code under trusted agent paths.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The module docstring explicitly describes a 'First-party standalone installer,' directly contradicting the metadata that presents the skill as a WeChat authorization/content-routing tool. Such contradiction is a red flag because it suggests capability concealment or at minimum misleading packaging, which can cause reviewers and users to misjudge the code's true behavior and risk.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The confirm helper immediately approves destructive actions when --yes or --confirm-local-changes is set, allowing unattended install/update flows to replace the destination skill directory with no interactive warning at execution time. In a script that downloads and installs packages into agent skill paths, this increases the risk of silent overwrite during automation, especially if invoked by wrappers or users who do not fully understand the effect of the flags.

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.