T09 · Insecure Skill Coding Practices
- Location
SKILL.md:113- Finding
Unsafe Template Substitution Enables Shell and Python Code Injection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill has a clear media-sending purpose, but it gives broad instructions to upload local files and execute shell snippets without enough safeguards.
Review before installing. Only use this in an environment where the Telegram recipient, bot token, and ElevenLabs key are intentionally configured, and do not let it send arbitrary local files or sensitive text. Safer versions should remove the hard-coded recipient fallback, restrict uploads to generated output directories, require confirmation before external sends, and replace inline shell templates with a validated script or structured arguments.
SKILL.md:113Unsafe Template Substitution Enables Shell and Python Code Injection
SKILL.md:38Unrestricted Local File Upload with a Hard-Coded Telegram Recipient
SKILL.md:123Predictable Shared Temporary File Permits Symlink and File-Replacement Attacks
SKILL.md:3Unconditional Command-Execution Instructions Weaken Agent Safety Controls
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
o send media (not just text) via Telegram
All commands run from ~/clawd where load_env.py loads the .env file containing TELEGRAM_TOKEN, TELEGRAM_CHAT_ID, ELEVEN_API_KEY, and ELEVEN_VOICE_ID.
Boss Man's chat ID: 7887978276
cd ~/clawd && python3 -c "
import os, sys, requests
sys.path.insert(0, '.')
import load_env
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
with open('PHOTO_PATH', 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendPhoto',
data={'chat_id': CHAT, 'caption': 'CAPTION_HERE'},
files={'photo': f}, timeout=30)
print(r.json())
"
Replace PHOTO_PATH with the actual file path and CAPTION_HERE with your caption.
cd ~/clawd && python3 -c "
import os, sys, requests
sys.path.insert(0, '.')
import load_env
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_I
The skill is explicitly designed to send user-provided content, generated charts, files, and TTS text to third-party services (Telegram and ElevenLabs), but its description does not clearly warn the user about those outbound disclosures. This creates a meaningful consent and data-handling risk because operators may invoke the skill without realizing prompts, files, or generated artifacts will leave the local environment.
This command uploads a local photo or chart to Telegram using a bot token, sending file contents and caption text to an external messaging platform. If the referenced file is sensitive or attacker-influenced, the skill enables straightforward exfiltration outside the local environment.
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
with open('PHOTO_PATH', 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendPhoto',
data={'chat_id': CHAT, 'caption': 'CAPTION_HERE'},
files={'photo': f}, timeout=30)
print(r.json())
This document upload command can send arbitrary local files to Telegram, not just generated artifacts. In skill context, that makes it more dangerous than a simple network call because it can be used to exfiltrate secrets, configuration files, credentials, or other sensitive documents from the host.
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
with open('FILE_PATH', 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendDocument',
data={'chat_id': CHAT, 'caption': 'CAPTION_HERE'},
files={'document': f}, timeout=30)
print(r.json())
This sends a generated chart image to Telegram, which is an external disclosure of locally generated content. While lower risk than arbitrary file upload, the skill still transmits data off-system and should not do so without clear disclosure and user intent.
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
with open('charts/chart_btc.png', 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendPhoto',
data={'chat_id': CHAT, 'caption': 'BTC — Daily TA Chart'},
files={'photo': f}, timeout=30)
print(r.json())
The bulk-send workflow iterates over all chart files and uploads them to Telegram, increasing the amount of data disclosed in a single command. Because it automates repeated external transmission, mistakes or stale/unintended files in the charts directory could be sent without granular review.
for chart in sorted(glob.glob('charts/chart_*.png')):
name = os.path.basename(chart).replace('chart_', '').replace('.png', '').upper()
with open(chart, 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendPhoto',
data={'chat_id': CHAT, 'caption': f'{name} — Daily TA Chart'},
files={'photo': f}, timeout=30)
print(f'Sent {name}: {r.status_code}')
This code sends arbitrary text content to ElevenLabs for speech generation, which is an external transmission to a third party. If the text contains sensitive user data, internal analysis, credentials, or regulated information, the skill will disclose it outside the trusted boundary.
API_KEY = os.getenv('ELEVEN_API_KEY') or os.getenv('ELEVENLABS_API_KEY')
VOICE_ID = os.getenv('ELEVEN_VOICE_ID', '1SM7GgM6IMuvQlz2BwM3')
text = '''TEXT_TO_SPEAK'''
r = requests.post(
f'https://api.xi-labs.com/v1/text-to-speech/{VOICE_ID}',
headers={'xi-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'text': text, 'model_id': 'eleven_multilingual_v2',
This is the concrete ElevenLabs API endpoint used to send text externally for TTS processing. In context, the risk is not the endpoint itself but the unguarded transfer of potentially sensitive text to a third party without clear notice or filtering.
VOICE_ID = os.getenv('ELEVEN_VOICE_ID', '1SM7GgM6IMuvQlz2BwM3')
text = '''TEXT_TO_SPEAK'''
r = requests.post(
f'https://api.xi-labs.com/v1/text-to-speech/{VOICE_ID}',
headers={'xi-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'text': text, 'model_id': 'eleven_multilingual_v2',
'voice_settings': {'stability': 0.5, 'similarity_boost': 0.75}},
This uploads the generated MP3 voice note to Telegram, exposing the spoken content to an external service. If the audio contains sensitive analysis or user data, the disclosure risk mirrors sending the raw text, with the added difficulty of auditing audio content after the fact.
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
with open('/tmp/frank_voice.mp3', 'rb') as f:
r = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendVoice',
data={'chat_id': CHAT, 'caption': 'Voice note from Frank'},
files={'voice': f}, timeout=30)
print(r.json())
The one-shot TTS workflow transmits user-supplied text to ElevenLabs before sending the resulting audio onward. This compounds disclosure risk because sensitive content may be exposed to multiple third-party services in a single action without separate confirmation.
TOKEN = os.getenv('TELEGRAM_TOKEN')
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
text = '''TEXT_TO_SPEAK'''
r = requests.post(
f'https://api.xi-labs.com/v1/text-to-speech/{VOICE_ID}',
headers={'xi-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'text': text, 'model_id': 'eleven_multilingual_v2',
This is another explicit ElevenLabs transmission point in the combined TTS-and-send workflow. It is dangerous because sensitive text is exported to ElevenLabs automatically as part of a chained action, reducing opportunities for operator review.
CHAT = os.getenv('TELEGRAM_CHAT_ID', '7887978276')
text = '''TEXT_TO_SPEAK'''
r = requests.post(
f'https://api.xi-labs.com/v1/text-to-speech/{VOICE_ID}',
headers={'xi-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'text': text, 'model_id': 'eleven_multilingual_v2',
'voice_settings': {'stability': 0.5, 'similarity_boost': 0.75}},
This sends the generated voice file to Telegram in the one-shot workflow, creating another external disclosure step. In combination with prior TTS generation, the skill can relay sensitive content through two external providers with minimal friction.
f.write(r.content)
import time; time.sleep(0.5)
with open('/tmp/frank_voice.mp3', 'rb') as f:
r2 = requests.post(f'https://api.telegram.org/bot{TOKEN}/sendVoice',
data={'chat_id': CHAT},
files={'voice': f}, timeout=30)
print(f'Voice sent: {r2.status_code}')
No suspicious patterns detected.