Back to skill

Security audit

约面招聘协调虾

Security checks for vulnerabilities and agentic risk

Overview

This interview-scheduling skill is mostly coherent, but its fallback script handles powerful calendar credentials unsafely and can mutate real calendars.

Review before installing. Prefer the openclaw-lark OAuth plugin path over the fallback script, grant Feishu and SMTP permissions narrowly, require confirmation before calendar or email changes, and do not use the fallback script in shared environments unless the token cache is moved to a private protected location or disabled.

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

Error
Location
scripts/feishu-calendar.sh:25
Finding

Predictable and Insecure Plaintext Access-Token Cache

Content
View full analysis

Vulnerability Details

File Location: scripts/feishu-calendar.sh, lines 25–52
Vulnerability Type: Insecure temporary file and plaintext credential storage
Risk Level: High

Vulnerable Code

bash
# 缓存 token 到文件(2小时有效)
TOKEN_CACHE="/tmp/feishu_interview_token_cache"

get_token() {
  if [[ -f "$TOKEN_CACHE" ]]; then
    cached=$(cat "$TOKEN_CACHE")
    expire=$(echo "$cached" | jq -r '.expire // 0')
    now=$(date +%s)
    if (( now < expire )); then
      echo "$cached" | jq -r '.token'
      return
    fi
  fi

  local resp
  resp=$(curl -s -X POST "$BASE_URL/auth/v3/tenant_access_token/internal" \
    -H "Content-Type: application/json" \
    -d "{\"app_id\":\"${FEISHU_APP_ID}\",\"app_secret\":\"${FEISHU_APP_SECRET}\"}")

  local token expire_at
  token=$(echo "$resp" | jq -r '.tenant_access_token // empty')
  if [[ -z "$token" ]]; then
    echo "ERROR: Failed to get token: $resp" >&2
    exit 1
  fi
  expire_at=$(( $(date +%s) + 7000 ))
  echo "{\"token\":\"$token\",\"expire\":$expire_at}" > "$TOKEN_CACHE"
  echo "$token"
}

Technical Analysis

The script stores a Feishu tenant access token as plaintext at the fixed, globally predictable path /tmp/feishu_interview_token_cache. It does not set a restrictive umask, explicitly apply mode 0600, verify file ownership, reject symbolic links, or create and replace the file atomically.

The resulting permissions depend on the process's existing umask. In an environment with a permissive umask, other local users may be able to read the bearer token. Because the path is predictable and the file is written using ordinary shell redirection, the implementation is also exposed to temporary-file race and symbolic-link risks where platform protections or directory permissions do not prevent them.

The cache is trusted solely based on its JSON expiration value. There is no validation that the file is owned by the ...[truncated 1802 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store the token in a private per-user runtime directory, preferably ${XDG_RUNTIME_DIR}, rather than a shared /tmp path.
  2. Set umask 077 before creating any file that contains credentials.
  3. Create the cache with mode 0600 and verify its ownership before reading it.
  4. Reject symbolic links and non-regular files. Where available, use APIs or utilities that provide O_NOFOLLOW-equivalent behavior.
  5. Write the cache atomically by creating a securely randomized temporary file in the same private directory, setting its permissions, and renaming it into place.
  6. Do not trust an existing cache unless its owner, permissions, type, and contents have been validated.
  7. Prefer an operating-system credential store or avoid persistent token caching if repeated authentication is acceptable.
  8. Remove the cache on termination when practical, and ensure expired cache files are securely deleted.
  9. Configure the Feishu application according to least privilege so that theft of a tenant token has the smallest possible impact.

A hardened implementation should use a pattern similar to:

bash
umask 077
CACHE_DIR="${XDG_RUNTIME_DIR:-$HOME/.cache}/feishu-interview"
mkdir -p -- "$CACHE_DIR"
chmod 700 -- "$CACHE_DIR"
TOKEN_CACHE="$CACHE_DIR/token.json"

tmp_file=$(mktemp "$CACHE_DIR/token.XXXXXX")
chmod 600 -- "$tmp_file"
jq -n --arg token "$token" --argjson expire "$expire_at" \
  '{token: $token, expire: $expire}' > "$tmp_file"
mv -f -- "$tmp_file" "$TOKEN_CACHE"

Before reading the cache, the script should also verify that it is a regular, non-symbolic-link file owned by the current user and not accessible by group or other users.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/feishu-calendar.sh (reported line 4)May include surrounding context.

sh
#!/usr/bin/env bash
# feishu-calendar.sh — 飞书日历 CLI(面试协调专用,支持视频会议)
# 用法:
#   ./scripts/feishu-calendar.sh token                    # 获取 access token
#   ./scripts/feishu-calendar.sh freebusy <user_id> <start> <end>  # 查询空闲(单用户)
#   ./scripts/feishu-calendar.sh freebusy-batch <user_ids_json> <start> <end>  # 批量查询
#   ./scripts/feishu-calendar.sh primary-calendar          # 获取主日历 ID

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/feishu-calendar.sh (reported line 168)May include surrounding context.

sh
#!/usr/bin/env bash
# feishu-calendar.sh — 飞书日历 CLI(面试协调专用,支持视频会议)
# 用法:
#   ./scripts/feishu-calendar.sh token                    # 获取 access token
#   ./scripts/feishu-calendar.sh freebusy <user_id> <start> <end>  # 查询空闲(单用户)
#   ./scripts/feishu-calendar.sh freebusy-batch <user_ids_json> <start> <end>  # 批量查询
#   ./scripts/feishu-calendar.sh primary-calendar          # 获取主日历 ID

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of shell scripts and SMTP/API operations but does not declare any explicit tool scope or allowed-tools boundaries. In an agent environment, this can lead to overbroad execution capability, making it easier for the skill to trigger shell-based actions or access external systems without clear least-privilege controls.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation phrases are broad enough to match ordinary scheduling language, which increases the chance the skill is invoked in contexts the user did not intend for interview coordination. Because the skill can query calendars and send messages, accidental activation may cause unintended access to employee availability data or outbound communications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill supports sending candidate emails via SMTP and processes personal data such as names, email addresses, interviewer identities, and scheduling details, but it does not clearly disclose that this data will be transmitted to external systems. This creates privacy and compliance risk, especially if users are not warned before PII leaves the platform or if SMTP endpoints are third-party managed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The reference explicitly instructs the skill to create, update, delete calendar events and send attendee notifications, but it provides no guardrails requiring explicit user confirmation before making externally visible changes. In this skill context, those actions can notify interviewers/candidates, create meetings, and alter real calendars at scale, so omission of confirmation and safety checks creates a genuine risk of unintended or unauthorized actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script caches the Feishu tenant access token in /tmp, a shared world-accessible location on many systems, without setting restrictive file permissions or warning the user. A local attacker or another process on the same host may read or reuse the token during its validity window to access calendar data or perform actions as the integration.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/feishu-calendar.sh (reported line 38)May include surrounding context.

sh
fi

  local resp
  resp=$(curl -s -X POST "$BASE_URL/auth/v3/tenant_access_token/internal" \
    -H "Content-Type: application/json" \
    -d "{\"app_id\":\"${FEISHU_APP_ID}\",\"app_secret\":\"${FEISHU_APP_SECRET}\"}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/feishu-calendar.sh (reported line 62)May include surrounding context.

sh
if [[ $# -ne 4 ]]; then echo "用法: freebusy <user_id> <start_rfc3339> <end_rfc3339>" >&2; exit 1; fi
    user_id="$2"; time_min="$3"; time_max="$4"
    token=$(get_token)
    curl -s -X POST "$BASE_URL/calendar/v4/freebusy/list?user_id_type=open_id" \
      -H "Authorization: Bearer $token" \
      -H "Content-Type: application/json" \
      -d "{\"user_id\":\"$user_id\",\"time_min\":\"$time_min\",\"time_max\":\"$time_max\",\"only_busy\":false}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/feishu-calendar.sh (reported line 121)May include surrounding context.

sh
}
      }')
    fi
    curl -s -X POST "$BASE_URL/calendar/v4/calendars/$cal_id/events" \
      -H "Authorization: Bearer $token" \
      -H "Content-Type: application/json" \
      -d "$local_body"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The delete-event command issues a DELETE request that removes a calendar event, which is an irreversible user-data operation. The script provides no confirmation prompt, cautionary comment, or user-facing warning immediately before performing the deletion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown content presents Chinese templates as the default and only later provides an English version, which can be interpreted as forcing a specific language by default. The file does not state that template language should be selected based on the candidate's preference or locale.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.