T09 · Insecure Skill Coding Practices
- Location
scripts/capture_visible_tweet.py:11- Finding
AppleScript Injection Through an Unescaped URL Argument
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a legitimate tweet-card purpose, but its screenshot helper can turn a crafted tweet URL into local AppleScript execution and may capture more browser content than intended.
Review this skill before installing. It is not clearly malicious, but only use it with trusted tweet URLs and a dedicated browser profile. Avoid running it on a normal logged-in Chrome window until the URL is strictly validated before browser navigation, AppleScript input is safely passed or escaped, and uncropped intermediate screenshots are deleted automatically.
scripts/capture_visible_tweet.py:11AppleScript Injection Through an Unescaped URL Argument
scripts/capture_visible_tweet.py:20Arbitrary Browser Navigation Due to Post-Navigation Substring Validation
scripts/capture_visible_tweet.py:15Overbroad Browser Capture and Persistent Storage of Uncropped Private Content
The script interpolates the untrusted tweet_url directly into AppleScript source and executes it via osascript. Because AppleScript string literals can be broken by crafted input, an attacker can inject additional AppleScript commands, potentially controlling local applications or executing shell commands through AppleScript on the host.
return u & "\n" & ((item 1 of b as text) & "," & (item 2 of b as text) & "," & (item 3 of b as text) & "," & (item 4 of b as text))
end tell
'''
res = subprocess.check_output(['osascript', '-e', script]).decode().splitlines()
current_url = res[0].strip()
if 'x.com/' not in current_url and 'twitter.com/' not in current_url:
raise SystemExit(f'Unexpected URL after navigation: {current_url}')
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
raise SystemExit(f'Unexpected URL after navigation: {current_url}')
left, top, right, bottom = map(int, res[1].split(','))
raw = out.parent / (out.stem + '.window.png')
subprocess.check_call(['/usr/sbin/screencapture', '-x', '-R', f'{left},{top},{right-left},{bottom-top}', str(raw)])
img = Image.open(raw).convert('RGBA')
W, H = img.size
# Main tweet column crop for desktop X layout; conservative and left-column focused.
The README states that the skill reads tweet content and may include metrics from external X/Twitter links, but it does not disclose this data-fetching behavior as a user-facing warning or note about external content processing. This is primarily a transparency and privacy-consent issue: users may not realize the skill will retrieve and process remote post data and associated metadata.