T09 · Insecure Skill Coding Practices
- Location
submit_directories.py:125- Finding
Sensitive information and credentials may be submitted over plaintext HTTP
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is not hidden malware, but it can automatically send credentials, contact details, and uploads to many third-party websites with insufficient safety checks.
Review before installing. Use only throwaway credentials, remove or disable plaintext HTTP and untrusted targets, inspect the generated submission_plan.json, and require manual confirmation before any password entry, OAuth flow, file upload, or final form submission. Run it in an isolated project with no unrelated secrets in the environment.
submit_directories.py:125Sensitive information and credentials may be submitted over plaintext HTTP
submit_directories.py:89Untrusted form metadata controls sensitive-value routing and automatic submission
requirements.txt:1Third-party dependency is installed using an open-ended version constraint without integrity locking
The code’s primary purpose is narrow: it loads URLs from JSON, opens them in headless Chromium, classifies whether pages are active/not found/parked/Cloudflare-blocked, detects likely auth methods and captcha technologies, and saves these annotations back to directories.json. This aligns only with a small subset of the declared 'analyzing directories' functionality. The description claims a much broader submission automation pipeline—collecting product info, discovering forms, auto-submitting, handling captchas/OAuth/GitHub PRs, and checkpoint tracking—but none of those active submission or workflow features appear in this code chunk. Because the implemented behavior is materially narrower and lacks several specifically declared capabilities, this is a description-to-behavior mismatch.
The declared description presents a comprehensive end-to-end submission automation skill. This code chunk is much narrower: it is a local data-cleanup and categorization utility for existing directory records. It does not browse sites, submit forms, handle authentication flows, solve captchas, create PRs, or track progress in checkpoint.md. While this script could be a supporting maintenance step within a larger directory-submission workflow, on its own it does not accurately represent the broad declared functionality, so the description materially overstates what the supplied code actually does.
The declared description presents a broad end-to-end submission system, but this code chunk is a narrower auto-submission executor. Its primary behavior is browser automation for filling and submitting forms on already-discovered directory pages. While this is consistent with part of the declared purpose, several prominently claimed capabilities are absent from the code: no directory analysis/discovery, no product-info collection, no captcha solving/handling beyond skipping matching fields, no OAuth or GitHub PR flow support, and no checkpoint.md tracking. The mismatch is therefore material because the description overstates what this supplied code chunk actually does.
The skill instructs loading a local .env via source, and the workflow relies on sensitive values like submission email, usernames, and passwords. In an agent context with file-read/env access, this increases the chance of credential exposure through logs, accidental file reads, downstream writes, or misuse by other steps interacting with third-party sites.
Tip: save these to a local .env file (already in .gitignore) and load with:
set -a && source .env && set +a
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
],
"site_status": "domain_dead",
"analysis_error": "<urlopen error [Errno -3] Temporary failure in name resolution>"
},
{
"categories": [
"General"
],
"description": "Submit your product to App Spy to reach your target audience.",
"is_active": true,
"name": "App Spy",
"pricing_type": "free",
"slug": "app-spy",
"submission_url": "https://www.appspy.com",
"url": "https://www.appspy.com",
"auth_type": "none",
"captcha_type": "none",
"requires_login": false,
"pricing_signals": [
"paid_signals"
],
"site_status": "active"
},
{
"categories": [
"General"
],
"description": "Submit your product to App Sumo to reach your target audience.",
"is_active": true,
"name": "App Sumo",
"pricing_type": "free",
"slug": "app-sumo",
"submission_url": "https://appsumo.com/sell",
"url": "https://appsumo.com/sell",
"auth_type": "google_only",
"captcha_type": "none",
The skill clearly expects access to environment variables, local files, and external network targets, yet it declares no explicit tool scope or allowed-tools boundary. In an agent setting, that makes the operational blast radius ambiguous and can permit broader-than-necessary access when handling credentials, reading .env, writing tracking files, and browsing third-party submission sites.
The script overwrites directories.json in place after processing without creating a backup, temporary file, or prompting the user. If execution is interrupted, results are malformed, or the input file was not meant to be mutated, this can cause data loss or corrupt workflow state, which is more concerning in a skill that tracks and transforms submission data across many sites.
The script reads URLs from JSON inputs and automatically launches a browser to visit them, which causes external network access to arbitrary third-party sites without any confirmation, allowlist, or safety gate. In the context of a submission automation skill, this increases risk of unintended contact with malicious or internal URLs, privacy leaks via browser fingerprinting/IP exposure, and possible SSRF-style access if an attacker can influence the URL list.
This code performs an in-place write to the primary data file, replacing its contents with modified data. Although the script prints a summary afterward, there is no user-facing warning or confirmation before the overwrite, and the module docstring does not disclose that it will modify the input file.
The manifest describes a skill for submitting products to AI/startup directories, but this file includes many targets that are not plausibly AI/startup directories, such as generic social platforms, subreddits, media outlets, local business listings, and broad web directories. That materially broadens the operational scope from directory submission to general internet promotion/distribution.
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
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.
"name": "Open Startup List",
"pricing_type": "free",
"slug": "open-startup-list",
"submission_url": "https://openstartuplist.com",
"url": "https://openstartuplist.com",
"auth_type": "none",
"captcha_type": "none",
The description explicitly labels this as a "Chinese AI Tools Directory," which bakes a locale/language constraint into the listing metadata without any indication of user opt-in or why that restriction is required. Under the policy, forcing a specific language or locale without choice or documented justification is a natural-language policy issue.
The description says "A french directory," which declares a fixed language/locale scope but does not offer any user choice or explain why that locale restriction is necessary. This matches the policy's prohibition on language or locale constraints that are not opt-in or clearly justified.
This code performs a file write that changes the existing submission_plan.json in place. Although the module docstring mentions updating the file, there is no runtime confirmation prompt or explicit user-facing warning immediately before the destructive overwrite, which can surprise users if they expected a read-only discovery pass.
Detected: suspicious.exposed_secret_literal, suspicious.install_untrusted_source