T09 · Insecure Skill Coding Practices
- Location
scripts/monitor.py:130- Finding
Unrestricted Channel URL Fetch Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill largely matches its YouTube transcription purpose, but it can store and later fetch arbitrary channel URLs, which may let it contact non-YouTube or internal network addresses.
Install only if you are comfortable with YouTube and AssemblyAI cloud processing. Use environment variables for the AssemblyAI key where possible, keep any config file private, and only add real YouTube HTTPS channel URLs until the skill validates channel destinations.
scripts/monitor.py:130Unrestricted Channel URL Fetch Enables Server-Side Request Forgery
SKILL.md:27AssemblyAI API Key May Be Stored in an Unprotected Plaintext Configuration File
The skill advertises capabilities that include environment access, file read/write, and network use, but it does not declare any explicit tool scope or permission boundaries. This increases the chance of over-broad execution in agent environments, making unintended data access, filesystem modification, or outbound requests harder to audit and restrict.
The activation guidance is broad enough to match common requests like summarization or monitoring, which can cause the skill to be invoked in situations beyond the user's likely intent. In an agentic system, over-broad routing can expose users to unnecessary network actions, third-party data transfer, or file operations when a simpler local skill would have sufficed.
The skill sends video-derived audio/transcription content to AssemblyAI, a third-party cloud service, but the markdown lacks a clear upfront warning to users about that transfer. This creates a privacy and consent risk because users may assume processing is local or limited to YouTube fetching, especially given the emphasis on 'pure Python' and 'zero local dependencies.'
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
SUMMARIES_DIR = DATA_DIR / "summaries"
CONFIG_FILE = DATA_DIR / "config.json"
API_BASE = "https://api.assemblyai.com/v2"
POLL_INTERVAL = 15
MAX_WAIT = 600
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
return None
body = {"videoId": video_id, "context": ctx}
resp = requests.post(
f"https://www.youtube.com/youtubei/v1/player?key={key}",
json=body,
headers={
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
return None
body = {"videoId": video_id, "context": ctx}
resp = requests.post(
f"https://www.youtube.com/youtubei/v1/player?key={key}",
json=body,
headers={
The skill sends YouTube-derived audio URLs and resulting transcript processing requests to AssemblyAI, a third-party cloud service, without any explicit consent, disclosure, or policy checks. In a monitoring/transcription skill this is core functionality, but it still creates a real privacy and data-governance risk because potentially sensitive media content is transmitted off-platform.
This request transmits audio source information to AssemblyAI for cloud transcription and summarization. Because the tool processes potentially sensitive content and sends it to an external processor, the risk is unauthorized disclosure, compliance issues, or user surprise if this transfer is not clearly disclosed and controlled.
"summary_type": "paragraph",
"summary_model": "conversational",
}
resp = requests.post(f"{API_BASE}/transcript", json=payload, headers=headers, timeout=30)
if resp.status_code != 200:
print(f" ERROR submit: {resp.status_code} {resp.text[:200]}")
return None
The function loads ASSEMBLYAI_API_KEY from an environment variable or data/config.json, which is sensitive credential material. There is no comment or warning advising users that a secret is being read from local config or environment, nor any note about protecting the config file.