Back to skill

Security audit

yoooclaw-company-info-personal

Security checks for vulnerabilities and agentic risk

Overview

This company lookup skill is purpose-related but needs Review because it sends employee identity, tokens, and company queries to a hardcoded non-HTTPS endpoint and stores credentials locally in plaintext.

Install only after confirming the API base URL is an organization-controlled HTTPS endpoint and that you trust the server receiving employee name, employee ID, bearer tokens, and company queries. Avoid shared machines unless the token cache is protected or moved to a secure credential store, and understand that refresh/re-search requests may trigger backend collection despite the read-only wording.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:91
Finding

Sensitive employee credentials and bearer tokens transmitted over plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 91-96; repeated at lines 147-153 and 183-194
Vulnerability Type: Plaintext transmission of sensitive information
Risk Level: High

Vulnerable Code

bash
# Call the auto-token endpoint
AUTO_TOKEN_URL="${COMPANY_INFO_API_URL:-http://47.116.49.218:3000/api}/auth/auto-token"

response=$(curl -s -X POST "$AUTO_TOKEN_URL" \
  -H "Content-Type: application/json" \
  -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\"}" \
  --max-time 10)

The plaintext default is also used during token renewal:

bash
AUTO_TOKEN_URL="${COMPANY_INFO_API_URL:-http://47.116.49.218:3000/api}/auth/auto-token"
EMPLOYEE_ID=$(jq -r '.employee_id' "$TOKEN_CACHE")
EMPLOYEE_NAME=$(jq -r '.employee_name' "$TOKEN_CACHE")

response=$(curl -s -X POST "$AUTO_TOKEN_URL" \
  -H "Content-Type: application/json" \
  -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\"}" \
  --max-time 10 > /dev/null 2>&1)

The bearer token and company query are similarly sent to a plaintext default endpoint:

bash
COMPANY_API_URL="${COMPANY_INFO_API_URL:-http://47.116.49.218:3000/api/company-info}"

FORCE_REFRESH=false
if 用户输入包含 ["重新搜索","更新","刷新","re-search","update","refresh"]; then
    FORCE_REFRESH=true
fi

if [ "$FORCE_REFRESH" = true ]; then
    echo "🔄 强制刷新模式,跳过公司端缓存..."
fi

response=$(curl -s -X POST "${COMPANY_API_URL}/collect" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"company_name\": \"${company_name}\", \"force_refresh\": ${FORCE_REFRESH}}" \
  --max-time 120)

status=$(echo "$response" | jq -r '.status')

Technical Analysis

The default API base URL uses unencrypted HTTP and a bare IP address. Unless every deployment explicitly overrides COMPANY_INFO_API_URL with a secure HTTPS endpoint, the Skill transmits the follow ...[truncated 2310 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the plaintext HTTP fallback and require an HTTPS URL:
    bash
    : "${COMPANY_INFO_API_URL:?COMPANY_INFO_API_URL must be configured with an HTTPS endpoint}"
    case "$COMPANY_INFO_API_URL" in
      https://*) ;;
      *) echo "Refusing non-HTTPS API endpoint" >&2; exit 1 ;;
    esac
    
  2. Use an organization-controlled DNS hostname with a certificate issued for that hostname rather than a bare IP address.
  3. Retain curl certificate verification and do not introduce -k or --insecure.
  4. Consider certificate or public-key pinning where the operational certificate-rotation process can support it safely.
  5. Rotate any tokens that may previously have crossed the plaintext endpoint.
  6. Restrict bearer tokens by role, endpoint, employee, and expiration time. Use short-lived access tokens where possible.
  7. Add server-side replay protections, access auditing, rate limits, and anomaly detection.
  8. Avoid placing sensitive identity or authentication material in URLs, logs, or diagnostic output.
  9. Fail closed when the endpoint is missing or insecure rather than silently falling back to HTTP.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:110
Finding

Bearer token and employee identity stored in a cleartext file without enforced restrictive permissions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 110-112; cache updates are repeated at lines 162-164
Vulnerability Type: Insecure local credential storage
Risk Level: Medium

Vulnerable Code

bash
# Save token cache
mkdir -p ~/.openclaw/workspace/scripts
echo "{\"token\": \"${API_TOKEN}\", \"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\", \"expires_at\": \"${expires_at}\", \"updated_at\": \"$(date -Iseconds)\"}" > "$TOKEN_CACHE"

The same unsafe storage pattern is used when the token is renewed:

bash
# Update cache silently
echo "{\"token\": \"${API_TOKEN}\", \"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\", \"expires_at\": \"${new_expires_at}\", \"updated_at\": \"$(date -Iseconds)\"}" > "$TOKEN_CACHE"

Technical Analysis

The Skill writes a reusable bearer token, employee ID, and employee name to:

text
~/.openclaw/workspace/scripts/.token-cache.json

The file is stored as plaintext, and the instructions do not establish a restrictive umask, set the parent directory to mode 700, or set the token file to mode 600. Consequently, effective permissions depend on the invoking process's existing umask and pre-existing directory permissions. In an insecure local configuration, another user or process may be able to read the credential.

The file is also overwritten directly rather than being securely and atomically replaced. This may expose partial content to concurrent readers and permits pre-existing filesystem objects to affect the write. In particular, if an attacker who can modify the cache path can place a symbolic link there, the shell redirection follows that link with the invoking user's privileges. The precise consequences depend on filesystem permissions available to the local attacker.

Attack Path

Credential disclosure path:

  1. The Skill initializes or renews an API token.
  2. The toke ...[truncated 1580 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer an operating-system credential store, such as macOS Keychain or Linux Secret Service, instead of a plaintext JSON file.
  2. If a file must be used, create it under a dedicated private directory and enforce restrictive permissions:
    bash
    TOKEN_DIR="$HOME/.openclaw/credentials"
    TOKEN_CACHE="$TOKEN_DIR/company-info-token.json"
    
    umask 077
    mkdir -p "$TOKEN_DIR"
    chmod 700 "$TOKEN_DIR"
    
  3. Write through a securely created temporary file in the same directory and atomically rename it:
    bash
    tmp_file=$(mktemp "$TOKEN_DIR/.token-cache.XXXXXX") || exit 1
    chmod 600 "$tmp_file"
    
    jq -n \
      --arg token "$API_TOKEN" \
      --arg employee_id "$EMPLOYEE_ID" \
      --arg employee_name "$EMPLOYEE_NAME" \
      --arg expires_at "$expires_at" \
      --arg updated_at "$(date -Iseconds)" \
      '{token:$token, employee_id:$employee_id, employee_name:$employee_name,
        expires_at:$expires_at, updated_at:$updated_at}' > "$tmp_file" || {
          rm -f "$tmp_file"
          exit 1
      }
    
    mv -f "$tmp_file" "$TOKEN_CACHE"
    chmod 600 "$TOKEN_CACHE"
    
  4. Before reading or replacing an existing cache, verify that it is a regular file owned by the current user and not a symbolic link.
  5. Avoid constructing JSON with shell string interpolation; use jq --arg or an equivalent serializer to preserve valid encoding.
  6. Store only the minimum required fields. Avoid retaining employee names if renewal does not require them.
  7. Use short-lived, narrowly scoped tokens and revoke tokens when local credential exposure is suspected.
  8. Document cleanup and revocation procedures for lost devices, shared workstations, and decommissioned employee environments.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger list includes broad terms such as '有限公司', '科技公司', '公司信息', and '工商信息', which are likely to appear in ordinary conversation. Overbroad triggers can cause the skill to activate unexpectedly and send company names or related context to external services without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly instructs silent token refresh and no user-facing notice before transmitting employee identity details to the auto-token endpoint. Silent collection and transmission of identifying information reduces informed consent and increases privacy and credential abuse risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill is presented as a simple personal company lookup tool, but it collects employee identity data, obtains an auth token, and persists both token and identity to local disk. This expands the trust boundary and creates credential/privacy risk that is not clearly disclosed to the user.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This code transmits employee ID and employee name to an external HTTP endpoint to obtain a token. Even if intended for legitimate authentication, it exposes personally identifying information over the network and, as written, defaults to a non-TLS http:// endpoint, which increases interception risk.

Content

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

md
# 调用 auto-token 接口
    AUTO_TOKEN_URL="${COMPANY_INFO_API_URL:-http://47.116.49.218:3000/api}/auth/auto-token"
    
    response=$(curl -s -X POST "$AUTO_TOKEN_URL" \
      -H "Content-Type: application/json" \
      -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\"}" \
      --max-time 10)

Session Persistence

Medium
Category
Rogue Agent
Confidence
96% confidence
Finding

The skill creates a local cache directory and writes token, employee ID, employee name, and expiry data to disk in plaintext JSON. Local persistence of credentials and identity data increases the risk of credential theft, lateral misuse, and privacy leakage from other local processes or users.

Content

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

md
expires_in_days=$(echo "$response" | jq -r '.expires_in_days')
        
        # 保存 Token 缓存
        mkdir -p ~/.openclaw/workspace/scripts
        echo "{\"token\": \"${API_TOKEN}\", \"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\", \"expires_at\": \"${expires_at}\", \"updated_at\": \"$(date -Iseconds)\"}" > "$TOKEN_CACHE"
        
        echo "✅ Token 获取成功(有效期 ${expires_in_days} 天)"

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This background renewal path silently retransmits stored employee identity data to the token service. The lack of user visibility and the repeated network transmission of PII increase privacy risk, and the same insecure default transport issue applies if COMPANY_INFO_API_URL is not overridden to HTTPS.

Content

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

md
EMPLOYEE_ID=$(jq -r '.employee_id' "$TOKEN_CACHE")
            EMPLOYEE_NAME=$(jq -r '.employee_name' "$TOKEN_CACHE")
            
            response=$(curl -s -X POST "$AUTO_TOKEN_URL" \
              -H "Content-Type: application/json" \
              -d "{\"employee_id\": \"${EMPLOYEE_ID}\", \"employee_name\": \"${EMPLOYEE_NAME}\"}" \
              --max-time 10 > /dev/null 2>&1)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation claims the personal skill is read-only, but the code can invoke POST /collect with force_refresh=true, causing server-side recollection or reprocessing. That is a capability mismatch which can trigger backend actions users may not expect and may bypass operational controls meant for collection workflows.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill sends company queries and authorization data to a remote collect endpoint, and can optionally trigger force_refresh to cause backend collection activity. This is expected behavior for the tool, but it remains security-relevant because it transmits potentially sensitive business queries and bearer tokens to a remote service.

Content

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

md
echo "🔄 强制刷新模式,跳过公司端缓存..."
fi

response=$(curl -s -X POST "${COMPANY_API_URL}/collect" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"company_name\": \"${company_name}\", \"force_refresh\": ${FORCE_REFRESH}}" \

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file claims the personal skill does not store data beyond session cache, but earlier code writes employee name, employee ID, token, and expiry metadata to ~/.openclaw/workspace/scripts/.token-cache.json. This misleading disclosure can cause users and reviewers to underestimate credential and privacy exposure.

Content

No source excerpt is available for this finding.

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:161