Back to skill

Security audit

wechat-new-tool

Security checks for vulnerabilities and agentic risk

Overview

This WeChat bridge can send messages for an account, but it exposes that power with poor safeguards and includes a reusable secret.

Review this carefully before installing. Only run it behind strong authentication and network restrictions, change the backend to HTTPS, remove and rotate the exposed WeChat token, pin dependencies with a lockfile, and require server-side confirmation tokens before any message can be sent.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
wechat_bridge.js:23
Finding

Unauthenticated Contact Enumeration and Arbitrary Message Sending

Content
View full analysis

Vulnerability Details

File Location: wechat_bridge.js, lines 23-71
Vulnerability Type: Missing authentication, missing authorization, and confirmation bypass
Risk Level: Critical

The service exposes contact-discovery and message-sending routes without any authentication or authorization middleware.

javascript
app.post('/wechat/dispatch', async (req, res) => {
    const { query, type, content, fileName } = req.body;

    try {
        const [friends, rooms] = await Promise.all([
            wx('/wechatTool/queryFriend', 'GET', { name: query }),
            wx('/wechatTool/queryChatroom', 'GET')
        ]);

        let matches = [...(friends.data || [])];
        if (rooms.data) {
            const roomMatches = rooms.data.filter(r => r.nickname.includes(query));
            matches = matches.concat(roomMatches);
        }

        if (matches.length > 1) {
            return res.json({
                status: "need_choice",
                data: matches.map(m => ({ name: m.nickname || m.remark, wxId: m.wxId }))
            });
        }

        const target = matches[0];
        res.json({
            status: "confirm",
            target_id: target.wxId,
            target_name: target.nickname || target.remark,
            payload: { type, content, fileName }
        });
    } catch (e) {
        res.status(500).json({ status: "error", msg: "service error" });
    }
});

app.post('/wechat/confirm_send', async (req, res) => {
    const { target_id, type, content, fileName } = req.body;
    const mapping = {
        text: { path: '/wechatTool/sendText', body: { contact: target_id, content } },
        image: { path: '/wechatTool/sendImg', body: { contact: target_id, content } },
        file: { path: '/wechatTool/sendFile', body: { contact: target_id, fileUrl: content, fileName } }
    };

    const config = mapping[type];
    const result = await wx(conf
...[truncated 2218 chars]
Remediation
View remediation

Remediation Suggestions

  • Require strong authentication for every route, such as mutually authenticated TLS or signed, short-lived service credentials.
  • Enforce server-side authorization that restricts which account, contacts, message types, and operations each caller may use.
  • Replace the client-managed confirmation convention with a server-side pending transaction.
  • After dispatch, issue a cryptographically random, short-lived, single-use confirmation token bound to the authenticated caller, target ID, message type, content digest, and file name.
  • Require that token at /wechat/confirm_send and reject altered, expired, replayed, or already-consumed transactions.
  • Do not expose raw WeChat identifiers unless strictly required; return opaque, short-lived selection identifiers instead.
  • Bind the service to a trusted interface and restrict port 3000 through firewall or service-mesh policy.
  • Add rate limiting, replay protection, request-size limits, audit logging, and alerting for unusual enumeration or sending activity.
  • Validate request bodies against a strict schema and allow only expected message types and payload formats.

T09 · Insecure Skill Coding Practices

Error
Location
wechat.yaml:3
Finding

Hardcoded WeChat Application Credentials

Content
View full analysis

Vulnerability Details

File Location: wechat.yaml, lines 3-4
Vulnerability Type: Plaintext credentials committed in project configuration
Risk Level: High

yaml
WECHAT_APPID: "wx_KcD1dMEn7KidBemwN2lVh"
WECHAT_TOKEN: "e4cf78e3-afdf-4a45-8090-143ab4df83f2"

Technical Analysis

The project contains a WeChat application identifier and bearer token in plaintext. Secrets stored in tracked configuration become available to anyone who can read the source package, repository history, build artifacts, backups, logs that print configuration, or copied deployment bundles.

The JavaScript bridge uses these values to identify the application and construct an Authorization: Bearer header for backend API calls. Therefore, the token is an authentication secret rather than harmless metadata.

Attack Path

  1. The attacker obtains a copy of the project, package, repository, build artifact, or configuration backup.
  2. The attacker extracts WECHAT_APPID and WECHAT_TOKEN from wechat.yaml.
  3. The attacker identifies the backend endpoint from wechat_bridge.js.
  4. The attacker attempts to submit API requests using the disclosed APPID and bearer token.
  5. If the credential remains active and is not additionally constrained, the backend processes requests under the configured application's privileges.

Impact Assessment

Successful credential reuse could allow unauthorized API access and impersonation of the configured application. Depending on backend authorization, an attacker may query account information, enumerate contacts, or send messages using the affected WeChat integration. The precise privilege scope is determined by the permissions assigned to this token. Because the credential has been distributed in plaintext, it must be treated as compromised even if direct exploitation has not been observed.

Remediation
View remediation

Remediation Suggestions

  • Revoke and rotate the exposed bearer token immediately.
  • Review backend access logs for use of the disclosed token from unexpected locations.
  • Remove all secrets from the current project and its repository history.
  • Inject credentials at deployment time through a managed secret store rather than a tracked YAML file.
  • Grant the replacement credential only the minimum API permissions required.
  • Apply expiration, rotation, source restrictions, and per-environment credentials.
  • Add secret-scanning checks to local development hooks and CI pipelines.
  • Ensure build artifacts, logs, diagnostics, and error reports do not expose environment values or authorization headers.

T09 · Insecure Skill Coding Practices

Error
Location
wechat_bridge.js:7
Finding

Bearer Token and Private WeChat Data Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: wechat_bridge.js, lines 7-20
Vulnerability Type: Cleartext transmission of credentials and sensitive data
Risk Level: High

javascript
const CONFIG = {
    BASE_URL: "http://dashboard.synodeai.com/ai",
    APPID: process.env.WECHAT_APPID,
    TOKEN: process.env.WECHAT_TOKEN
};

const wx = async (path, method, data = {}) => {
    return axios({
        url: `${CONFIG.BASE_URL}${path}`,
        method: method,
        headers: { 'Authorization': `Bearer ${CONFIG.TOKEN}` },
        params: method === 'GET' ? { appid: CONFIG.APPID, ...data } : { appid: CONFIG.APPID },
        data: method === 'POST' ? data : null
    });
};

Technical Analysis

The backend base URL uses unencrypted HTTP while every request includes a bearer token and application identifier. GET requests can also contain contact search data in the query string, while POST bodies can contain target identifiers, message text, media URLs, and file names.

HTTP provides neither transport confidentiality nor endpoint integrity. An attacker with visibility or control over the network path can inspect authorization headers and private data. An active attacker can also modify requests or responses, including recipient identifiers, message content, contact results, and API status data.

Attack Path

  1. The attacker gains a position on the traffic path, such as a shared network, compromised router, proxy, DNS path, hosting network, or upstream provider.
  2. The bridge sends a request to http://dashboard.synodeai.com/ai.
  3. The attacker captures the plaintext Authorization header, APPID, query parameters, and message data.
  4. The attacker replays the bearer token against the backend while it remains valid.
  5. Alternatively, the attacker modifies an in-transit request to change the recipient or message payload, or alters contact-query responses returned to the bridge.

Impact Asse

...[truncated 469 chars]

Remediation
View remediation

Remediation Suggestions

  • Change the backend URL to HTTPS and ensure the remote service supports modern TLS.
  • Reject redirects that downgrade requests from HTTPS to HTTP.
  • Retain normal certificate and hostname verification; do not disable Axios or Node.js TLS validation.
  • Consider certificate or public-key pinning where the operating environment and rotation process can support it safely.
  • Rotate the bearer token because it may already have traversed untrusted networks in plaintext.
  • Use short-lived, narrowly scoped credentials so intercepted tokens have limited value.
  • Avoid placing sensitive values in query strings because URLs are commonly retained by proxies and logs.
  • Minimize the contact and message data transmitted to the remote service.
  • Apply outbound network controls so the process can connect only to the approved HTTPS endpoint.
  • Monitor for DNS changes, certificate errors, unexpected redirects, and anomalous token use.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This service exposes message-sending and contact-query capabilities over unauthenticated HTTP endpoints while using environment-backed WeChat credentials to act on behalf of an account. An attacker who can reach the server can enumerate contacts and send arbitrary text, images, or files to WeChat targets, causing impersonation, spam, data leakage, or malware/file delivery through a trusted channel.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The request wrapper transmits the app ID and request data to an external service, and later routes use it to send message content and file metadata. There is no confirmation prompt, logging, comment, or other user-facing disclosure in this code explaining that user-provided content will be sent over the network.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency uses a caret range (^1.6.0), which permits automatic installation of newer minor/patch releases rather than a single audited version. This weakens supply-chain reproducibility and can unintentionally introduce vulnerable or malicious updates, especially since the project appears to act as a network-facing bridge service.

Content

Scanner excerpt · package.json (reported line 5)May include surrounding context.

json
"name": "wechat-ai-bridge",
  "version": "1.0.0",
  "dependencies": {
    "axios": "^1.6.0",
    "express": "^4.18.0"
  },
  "scripts": {

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +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
91% confidence
Finding

Axios has multiple known advisories, and because the manifest does not pin the exact installed version, it is impossible to verify from this file alone whether the deployed package is affected. In a bridge service that likely makes outbound HTTP requests, an affected axios version could expose the application to issues such as SSRF-related bypasses, request manipulation, or other client-side HTTP security flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The express dependency is specified with a caret range (^4.18.0), so installs are not guaranteed to use one exact vetted version. This creates a supply-chain risk where future installs may pull in different code, including versions with newly disclosed vulnerabilities or compromised releases.

Content

Scanner excerpt · package.json (reported line 6)May include surrounding context.

json
"version": "1.0.0",
  "dependencies": {
    "axios": "^1.6.0",
    "express": "^4.18.0"
  },
  "scripts": {
    "start": "node wechat_bridge.js"

Unverifiable Dependency: express has 5 known advisory(ies) (CVE-2024-10491 (Express ressource injection); CVE-2014-6393 (No Charset in Content-Type Header in express); CVE-2024-9266 (Express Open Redirect vulnerability) +2 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding

Express has known advisories, and the unpinned version range prevents confirmation that the deployed release is safe. Because Express is typically used for network-exposed server endpoints, running an affected version could increase exposure to web issues such as open redirect or other framework-level flaws depending on the actual installed release and application code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code reads WECHAT_APPID and WECHAT_TOKEN from environment variables, which are sensitive configuration values. The file provides no comment, warning, or user-facing notice about accessing credentials or how they are used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The code includes user-facing response messages only in Chinese, such as the not-found and service-error messages. This imposes a language choice without any opt-in or documented locale constraint.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
wechat_bridge.js:9