T09 · Insecure Skill Coding Practices
- Location
scripts/send_voice_feishu.sh:51- Finding
Arbitrary Python Code Execution Through an Untrusted Audio Filename
- Content
View full analysis
Vulnerability Details
File Location:
scripts/send_voice_feishu.sh, lines 51–61
Vulnerability Type: Python source-code injection
Risk Level: HighVulnerable Code:
bash # 计算音频时长(毫秒),用于后续发送消息时传入 duration 字段 DURATION_MS=$(python3 -c " import wave, os try: with wave.open('$WAV_FILE') as f: frames = f.getnframes() rate = f.getframerate() print(int(frames / rate * 1000)) except Exception as e: print(0) ")Technical Analysis
WAV_FILEoriginates from the first command-line argument and is interpolated directly into source code passed topython3 -c. Shell quoting around the outer command does not make this safe because the expanded value becomes part of the Python program.A filename containing a single quote, Python delimiters, and additional statements can terminate the argument to
wave.open, alter the generated Python program, and execute attacker-selected Python code. The preceding file-existence check only verifies that the supplied pathname exists; it does not validate or neutralize characters that are meaningful in Python source.The vulnerable duration calculation occurs after Feishu credentials have been loaded from
FEISHU_APP_IDandFEISHU_APP_SECRET. Injected code therefore executes in a process environment that can access those credentials.Attack Path
- An attacker creates or causes the user to receive a file whose pathname contains Python source-code metacharacters.
- The attacker persuades the user or an automated workflow to invoke
send_voice_feishu.shwith that pathname as the first argument. - The pathname passes the
[ -f "$WAV_FILE" ]existence check. - The shell expands
$WAV_FILEinside the program supplied topython3 -c. - The embedded quote terminates the intended Python string, and attacker-controlled statements become executable Python source.
- Python executes those statements with the permissi ...[truncated 653 chars]
- Remediation
View remediation
Remediation Suggestions
Never interpolate a pathname into generated Python source. Pass it as a positional argument and read it through
sys.argv:bash DURATION_MS=$(python3 -c ' import sys import wave try: with wave.open(sys.argv[1]) as audio: frames = audio.getnframes() rate = audio.getframerate() print(int(frames / rate * 1000)) except Exception: print(0) ' "$WAV_FILE")Additional hardening should include:
- Use
set -euo pipefailand reference optional environment variables as${FEISHU_APP_ID:-}and${FEISHU_APP_SECRET:-}. - Treat all command-line pathnames as untrusted and pass them only as quoted data arguments.
- Avoid constructing source code, JSON, or shell commands through string interpolation.
- Add regression tests using filenames containing quotes, spaces, newlines, leading hyphens, and shell or Python metacharacters.
- Run the Skill under an unprivileged account and provide Feishu credentials only for the duration of the send operation.
- Use
