T09 · Insecure Skill Coding Practices
- Location
scripts/scan_favorites.py:203- Finding
Automatic Requests to Untrusted Inventory-Derived URLs
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its cataloging purpose, but it automatically scans broad local inventory and contacts inventory-derived external URLs without clear opt-in or network bounds.
Review before installing. Use only in an environment where broad local software inventory collection is acceptable, and avoid running it with network access unless you are comfortable disclosing discovered repository, app, package, or extension URLs to GitHub and vendor domains. Treat --limit-source as unsafe for an existing catalog unless the deletion behavior is fixed or backed up first.
scripts/scan_favorites.py:203Automatic Requests to Untrusted Inventory-Derived URLs
scripts/scan_favorites.py:986Partial Source Scans Delete Unrelated Catalog Entries
The skill instructs the agent to run local Python scripts that enumerate repositories, applications, skills, extensions, hooks, and installed packages, and to write snapshots, reports, and cache files, but it declares no explicit tool scope or permission boundaries. Because the skill implicitly relies on shell, file read/write, environment access, and potentially network-enabled enrichment, an agent may execute broad local inventory and persistence actions without user-visible least-privilege constraints, increasing the risk of overcollection, unintended data exposure, or misuse if the scripts are modified or malicious.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
import hashlib
import json
import os
import plistlib
import re
import subprocess
from collections import defaultdict
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def run(cmd):
try:
return subprocess.run(cmd, capture_output=True, text=True, check=True)
except (FileNotFoundError, subprocess.CalledProcessError):
return None
Although the skill is presented as a local-first favorites cataloger, it performs outbound requests to enrich entries with remote metadata. This leaks locally discovered repository and software URLs to third parties such as GitHub and any referenced vendor domains, creating unnecessary external transmission and scope expansion beyond the advertised behavior.
The script performs remote enrichment and then persists both cache data and generated catalog files locally without an explicit warning to the user in the execution path. This combination can silently create durable records of external lookups and enriched metadata, surprising users who expected only local scanning.
The generic fetch_text capability allows retrieval of arbitrary external URLs derived from locally discovered metadata, which is broader than necessary for local inventory generation. In practice, this enables the skill to contact attacker-controlled or privacy-sensitive endpoints and pull untrusted content into the enrichment workflow.
This outbound call sends repository identifiers extracted from local installations to the GitHub API, which is an external transmission of locally derived metadata. Even if the data is not highly sensitive by itself, it reveals aspects of the user's installed tools and repositories and contradicts the local-first framing of the skill.
if cached:
return cached
try:
data = fetch_json(f'https://api.github.com/repos/{repo_key}')
except (HTTPError, URLError, TimeoutError, IncompleteRead, RemoteDisconnected, json.JSONDecodeError, OSError):
return None
payload = {
The code fetches arbitrary non-GitHub source URLs and parses remote HTML for metadata, even though the skill's stated purpose is local cataloging. Because source URLs come from local repositories, package metadata, and app metadata, this can trigger unsolicited requests to many external domains and disclose parts of the user's local software inventory.
The document permits optional GitHub API and vendor homepage fetching for enrichment but does not specify any user consent, notification, or opt-in requirement before network access occurs. In a local-inventory skill, silent outbound requests can disclose installed software, repository metadata, or browsing targets to third parties and may violate user expectations in privacy-sensitive environments.
No suspicious patterns detected.