Back to skill

Security audit

crm-sync-assistant

Security checks for vulnerabilities and agentic risk

Overview

This CRM assistant has a coherent business purpose, but it handles employee passwords, bearer tokens, and CRM records in ways that are too risky for automatic installation.

Install only if you trust the CRM operator and can tolerate the skill handling employee passwords and CRM data. Before production use, require HTTPS, remove token-in-URL fallback, replace chat passwords with a secure login flow, store tokens in a credential store or locked-down file, narrow the triggers, and document manager/subordinate access clearly.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:154
Finding

Employee Credentials and Bearer Tokens Transmitted Over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:175
Finding

Bearer Tokens Stored in an Unprotected Plaintext Cache

Content
View full analysis
"$TOKEN_CACHE" ``` Equivalent plaintext writes also occur after password changes, account switches, expired-token logins, and token renewals. ### Technical Analysis The Skill stores a reusable bearer token in a JSON file under `~/.openclaw/workspace/scripts/.token-cache.json`. It does not set a restrictive `umask`, apply mode `0600`, verify file ownership, use atomic secure file creation, or use an operating-system credential store. The final permissions depend on the process environment and existing directory configuration. In a shared workspace, another local process, Skill, plugin, backup process, or user account may be able to read the token. The cache also contains employee identity information and may persist across sessions for the token's full lifetime. Because a bearer token grants access based solely on possession, reading this file can be sufficient to impersonate the employee without knowing the password. ### Attack Path 1. The victim authenticates through the Skill. 2. The Skill receives a bearer token and writes it as plaintext to `.token-cache.json`. 3. Another local process or component with access to the workspace reads the cache file. 4. The attacker extracts the token. 5. The attacker sends authenticated requests to ...[truncated 689 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:351
Finding

Full Bearer Token Exposed in Plaintext H5 URL Fallback

Content
View full analysis
`. 5. The URL is emitted into the conversation and opened over plainte ...[truncated 794 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:470
Finding

Unpinned Third-Party Package Installed and Executed at Runtime

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (22)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill instructs the AI to extract account IDs and passwords from free-form chat and reuse them for authentication, without masking, minimization, or a safer delegated login flow. This is dangerous because conversational channels are often logged, retained, or visible to intermediaries, making raw credential handling a serious exposure path.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly says raw tokens must not be exposed in URLs, but the fallback logic appends the full bearer token as a query parameter. Tokens in URLs can leak through browser history, logs, referer headers, screenshots, proxies, and shared links, which could allow account takeover or unauthorized CRM access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The description defines invocation and usage entirely in Chinese and does not state that the skill is China-only or otherwise locale-restricted. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale constraint is clearly justified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Several trigger patterns are broad enough to activate on ordinary project-related conversation, which can unintentionally launch a skill that accesses CRM records, visit records, or synchronization flows. In a security-sensitive assistant, accidental routing matters because it may expose internal data or prompt for credentials in the wrong conversational context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Patterns targeting broad employee-data requests can overmatch requests about staff activity or team projects that were not meant for CRM access. Because this skill can query subordinate data, ambiguous routing increases privacy risk and could surface sensitive team information unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill can access and display subordinate employees’ CRM data for managers, but that capability is not prominently disclosed in the high-level description. Hidden scope expansion around employee data creates privacy and governance risk, especially in enterprise settings where users may assume self-only access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation claims all queries only return the current user's own data, but later supports subordinate lookups and team-wide queries. This inconsistency can mislead reviewers and users about the skill’s real data-access scope, increasing the chance of overbroad disclosure or accidental invocation of managerial data views.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill directs silent retention and reuse of authentication material across sessions, reducing user awareness and increasing the blast radius if local state is exposed. Persistent auth reuse is especially risky here because the same skill can access CRM and subordinate-related data depending on role.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill collects employee credentials from chat and caches authentication material locally, but this sensitive handling is not clearly disclosed up front in the user-facing description. Users may provide credentials without understanding storage and reuse behavior, which increases privacy and account-risk concerns.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This sends employee credentials to an external service over HTTP, not HTTPS, which exposes them to interception on the network. The transmission itself is expected for authentication, but using cleartext transport makes it a genuine security vulnerability.

Content

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

md
# AI 从用户回复中提取 employee_id(账号)和 password(密码)
    # 用户输入示例:"emp-server-106 123456" 或 "我的账号是 emp-server-106,密码是 123456"

    response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/login" \
      -H "Content-Type: application/json" \
      -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"password\": \"${PASSWORD}\"}" \
      --max-time 120)

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

The skill persists authentication tokens and employee identifiers in a workspace file under the user home directory, with no mention of encryption, permission hardening, or secure storage. Local compromise, backup leakage, or cross-process access could expose reusable session material.

Content

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

md
employee_name=$(echo "$response" | jq -r '.data.employee_name')
        must_change_pw=$(echo "$response" | jq -r '.data.must_change_pw')

        mkdir -p ~/.openclaw/workspace/scripts
        echo "{\"token\": \"${API_TOKEN}\", \"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${employee_name}\", \"expires_at\": \"${expires_at}\", \"updated_at\": \"$(iso_now)\"}" > "$TOKEN_CACHE"

        # 首次登录强制改密检测

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The password-change flow transmits both old and new passwords to an external endpoint over plain HTTP. Exposure of either credential in transit can lead to immediate account compromise and persistent unauthorized access.

Content

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

md
echo "请输入新密码(至少6位):"
            echo "(等待用户输入新密码...)"

            pw_response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/change-password" \
              -H "Content-Type: application/json" \
              -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"old_password\": \"${PASSWORD}\", \"new_password\": \"${NEW_PASSWORD}\"}" \
              --max-time 120)

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This login request again transmits a password externally over HTTP during account-switch handling. Although authentication requires transmission, the insecure transport and chat-derived secret handling make this a real confidentiality risk.

Content

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

md
echo "🔑 检测到账号切换,请重新输入密码"
        echo "(等待用户输入密码...)"

        response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/login" \
          -H "Content-Type: application/json" \
          -d "{\"employee_id\": \"${INPUT_EMPLOYEE_ID}\", \"password\": \"${PASSWORD}\"}" \
          --max-time 120)

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

This is another path that writes refreshed or switched-account authentication material into the same local cache. Repeated persistence of active session tokens without secure storage broadens the chance of unauthorized reuse across accounts.

Content

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

md
employee_name=$(echo "$response" | jq -r '.data.employee_name')
            EMPLOYEE_ID="$INPUT_EMPLOYEE_ID"
            EMPLOYEE_NAME="$employee_name"
            mkdir -p ~/.openclaw/workspace/scripts
            echo "{\"token\": \"${API_TOKEN}\", \"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\", \"expires_at\": \"${new_expires}\", \"updated_at\": \"$(iso_now)\"}" > "$TOKEN_CACHE"
        else
            error_message=$(echo "$response" | jq -r '.message')

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This re-login path sends credentials to the external login endpoint over plain HTTP after token expiry. Repeated insecure credential transmission increases exposure opportunities and undermines the token refresh design.

Content

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

md
echo "请输入您的账号和密码,格式:账号 密码"
            echo "(等待用户输入...)"

            response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/login" \
              -H "Content-Type: application/json" \
              -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"password\": \"${PASSWORD}\"}" \
              --max-time 120)

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The renew-failure fallback again transmits the user password to an external service over HTTP. The issue is compounded by repeated prompting for secrets and conversational extraction of passwords.

Content

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

md
echo "⚠️ Token 续期失败,请重新输入密码"
                echo "(等待用户输入密码...)"

                response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/login" \
                  -H "Content-Type: application/json" \
                  -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"password\": \"${PASSWORD}\"}" \
                  --max-time 120)

External Transmission

Medium
Category
Data Exfiltration
Confidence
85% confidence
Finding

The exchange-code request sends a bearer token to an external API over plain HTTP. Even though this is a token exchange rather than password transmission, interception would still allow session hijacking or downstream link issuance.

Content

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

md
H5_BASE_URL="http://47.116.49.218:5173"

# 获取换码(一次性短码,5分钟有效)
exchange_response=$(curl -s -X POST "${FASTAPI_BASE_URL}/auth/exchange-code" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{}' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The sync call transmits CRM lead data and an authorization token to an external endpoint over HTTP. This can leak sensitive customer/project data and enable unauthorized API use if intercepted.

Content

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

bash
# 同步数据至 CRM
curl -s -X POST "${FASTAPI_BASE_URL}/crm-leads/sync" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
SKILL.md:416