T09 · Insecure Skill Coding Practices
- Location
scripts/fathom-get-transcript.sh:11- Finding
Recording ID Allows Arbitrary Python Code Injection
- Content
View full analysis
}" API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}" # Fetch recent meetings with transcripts and filter for the requested one curl -sS "https://api.fathom.ai/external/v1/meetings?limit=100&include_summary=true&include_transcript=true" \ -H "X-Api-Key: ${API_KEY}" \ | python3 -c " import json, sys data = json.load(sys.stdin) target = int('${RECORDING_ID}') for item in data.get('items', []): if item.get('recording_id') == target: print(json.dumps(item, indent=2)) sys.exit(0) print(json.dumps({'error': 'Meeting not found', 'recording_id': target})) sys.exit(1) " ``` ### Technical Analysis `RECORDING_ID` is obtained directly from the first command-line argument and interpolated into a Python program passed to `python3 -c`. Shell quoting does not make the value safe for inclusion in Python source code. An attacker-controlled value can close the Python string and `int()` expression, append arbitrary Python statements, and comment out the remaining generated source. For example, a value shaped like: ```text 1'); __import__('os').system('id'); # ``` would transform the relevant generated source into the equivalent of: ```python target = int('1'); __import__('os').system('id'); #') ``` The injected statement is then evaluated by the local Python interpreter. The use of `set -euo pipefail` does not prevent this because the injection occurs within syntactically valid Python executed as part of the pipeline. ### Attack Path 1. An attacker supplies, or causes the Agent to extract, a malicious value as a Fathom recording ID. 2. The transcript workflow invokes: ```bash bash "$_SKILL_DIR/scripts/fathom-get ...[truncated 1205 chars]- Remediation
View remediation
}" API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}" if [[ ! "$RECORDING_ID" =~ ^[0-9]+$ ]]; then printf 'Invalid recording ID: expected digits only\n' >&2 exit 2 fi curl -sS \ "https://api.fathom.ai/external/v1/meetings?limit=100&include_summary=true&include_transcript=true" \ -H "X-Api-Key: ${API_KEY}" \ | python3 -c ' import json import sys data = json.load(sys.stdin) target = int(sys.argv[1]) for item in data.get("items", []): if item.get("recording_id") == target: print(json.dumps(item, indent=2)) sys.exit(0) print(json.dumps({"error": "Meeting not found", "recording_id": target})) sys.exit(1) ' "$RECORDING_ID" ``` This separates executable Python source from untrusted input and removes the injection primitive. ]]>
