T09 · Insecure Skill Coding Practices
- Location
scripts/technical-audit.sh:14- Finding
Arbitrary Python Code Execution Through URL Interpolation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real SEO/GEO audit skill, but it needs Review because crafted inputs can execute code or write outside the intended workspace, and external API/credential use is under-scoped.
Do not run this skill on untrusted URLs, internal services, staging hosts, or client-confidential keyword sets until the input handling is fixed. Use a sandboxed environment, restrict network egress, use dedicated low-privilege API keys, avoid Owner or Full service-account permissions, and review or delete the persisted audit workspace after use.
scripts/technical-audit.sh:14Arbitrary Python Code Execution Through URL Interpolation
scripts/audit-page.sh:39Server-Side Request Forgery Through Unrestricted Audit URLs
scripts/track-keywords.sh:18Workspace Path Traversal Through Unvalidated Site Identifiers
scripts/audit-technical.sh:113PageSpeed API Key Exposed in Request Query String
SKILL.md:11Unpinned Runtime Dependencies Create Supply-Chain Risk
The code materially underdelivers relative to the declared description. Its actual purpose is narrowly a GEO audit for a single URL, not a comprehensive SEO/GEO toolkit. It does perform one declared area—GEO readiness evaluation for AI search engines—and saves a local report, but there is no evidence in this chunk of competitor analysis, keyword tracking, broad technical SEO auditing, PDF generation, or time-series monitoring. Resource access is broadly consistent with auditing a website (HTTP fetch of the target URL and local file write), and there are no suspicious unrelated capabilities. However, the declared description significantly overstates the functionality represented by this code chunk, so this should be flagged as a mismatch.
The code does match one declared area: on-page SEO auditing of a single page. However, the declared description presents a much broader and more comprehensive toolkit, including competitor analysis, keyword tracking, GEO scoring, PDF generation, and ongoing monitoring. None of those capabilities appear in this code chunk. The script only fetches one URL, evaluates basic on-page signals, writes a JSON file, and prints a terminal summary. While storing audit files under timestamped paths could support later historical review, the code itself does not implement monitoring or trend analysis. Therefore the supplied code chunk materially underdelivers relative to the declared purpose, so this is a description-behavior mismatch.
The code is related to SEO auditing, so it partially matches the broad domain, but the declared description substantially overstates the implemented functionality in this supplied chunk. The actual script only performs a technical SEO audit and optional PageSpeed lookup for a single URL, storing results locally as JSON. There is no evidence here of competitor analysis, keyword ranking tracking, GEO readiness/scoring, PDF generation, or broader comprehensive toolkit behavior. Because the declared purpose presents a much wider set of core capabilities than the code actually provides, this is a meaningful description-behavior mismatch.
The code chunk is a report generator script, not a comprehensive SEO/GEO audit toolkit. It reads existing audit JSON files from a local workspace and writes a .md report. While this partially aligns with the declared reporting/audit context, several prominently declared capabilities are absent in the supplied code: no crawling or audit execution, no competitor analysis, no keyword tracking, no time-series monitoring logic, and no PDF generation. The actual primary purpose of this code is narrower than advertised, so the description does not accurately represent what this code chunk actually does.
The code substantially matches part of the description: it performs on-page SEO checks, technical SEO checks, content/schema/social checks, and a basic GEO readiness score for a supplied URL. However, the declared description presents a broader 'comprehensive' toolkit with competitor analysis, keyword tracking, PDF report generation, client reporting, and monitoring over time. None of those capabilities appear in this code chunk. The code only fetches a single page via HTTP, parses HTML, computes scores/issues, prints a console summary, and optionally writes JSON output. Because several headline capabilities in the declared purpose are absent and the actual scope is materially narrower, this is a description-behavior mismatch.
The provided code chunk only demonstrates crawling a single site and invoking an SEO audit for each page, then printing and saving a JSON summary. That partially matches the declared on-page/technical SEO audit functionality. However, the declared description presents a much broader toolkit with competitor analysis, keyword ranking tracking, GEO readiness scoring, PDF report generation, and longitudinal monitoring, none of which are evidenced in this code chunk. There are no suspicious undeclared capabilities beyond normal web fetching and file output for the audit task, but the description materially overstates the implemented functionality shown here.
The declared description presents a broad, comprehensive SEO and GEO toolkit with multiple major capabilities, including competitor analysis, keyword tracking, GEO readiness scoring, PDF report generation, and longitudinal monitoring. The supplied code chunk does not implement those features. Instead, it performs a narrow technical audit: HTTP status/load timing, HTTPS/redirect checks, robots.txt inspection including AI bot blocking, sitemap presence, and optional PageSpeed API scoring. While this does fit one subset of the declared purpose—technical SEO checks—it materially underdelivers relative to the comprehensive toolkit description. There is no evidence in this chunk of competitor analysis, keyword rank tracking, GEO scoring logic, PDF generation, or time-series monitoring. Therefore the description does not accurately represent what this code chunk actually does.
The script embeds the user-controlled URL directly into a Python string inside a python3 -c one-liner. An attacker can supply a crafted URL containing quotes and Python syntax to break out of the string and execute arbitrary Python code on the host, which goes far beyond the intended GEO audit behavior.
The skill advertises and documents capabilities that use network access, environment variables, and persistent file read/write, but it does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, missing scope declarations can cause the skill to be invoked with broader privileges than users expect, increasing the chance of unintended data access, outbound requests, or filesystem modification.
The skill performs outbound requests to websites and third-party APIs/search services, but the description does not warn users that target URLs, keywords, and potentially business-sensitive audit data may be transmitted externally. This can create privacy, confidentiality, and compliance risks, especially for client work or internal domains.
The guide explicitly instructs users to create and download a service-account JSON key, which is a highly sensitive credential that can grant API access if exposed. Omitting handling, storage, rotation, and least-privilege guidance increases the chance that users will save, share, commit, or distribute the key insecurely.
The script accesses BRAVE_API_KEY from the environment and uses it to authenticate outbound requests, but there is no warning or disclosure that credential material will be consumed for network activity. The surrounding output only reports failure states and does not clearly tell the user that an environment-provided API key will be used.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
if brave_key:
try:
search_resp = requests.get(
"https://api.search.brave.com/res/v1/web/search",
headers={"X-Subscription-Token": brave_key},
params={"q": keyword, "count": 10},
timeout=10
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
if brave_key:
try:
search_resp = requests.get(
"https://api.search.brave.com/res/v1/web/search",
headers={"X-Subscription-Token": brave_key},
params={"q": keyword, "count": 10},
timeout=10
The script performs an outbound HTTP request to a user-supplied URL and writes a detailed report to local storage without any explicit user-facing disclosure or confirmation. In an agent setting, hidden network access and filesystem writes can surprise users, expose internal URLs or browsing targets, and leave potentially sensitive audit artifacts on disk.
The script automatically sends the user-supplied target URL and a locally available PAGESPEED_API_KEY to Google's external PageSpeed API without any user-facing notice, consent, or opt-in. This can unintentionally disclose sensitive audit targets, internal/staging URLs, or usage tied to the operator's API key to a third party, which is especially risky in an agent skill that may be run on arbitrary user-provided URLs.
User-supplied keywords are sent to Brave's external search API, which can expose potentially sensitive client strategy, campaign terms, or unreleased business priorities to a third party. While this is necessary for the feature to work, the script does not provide explicit disclosure or consent at the point of transmission, creating a privacy and data-handling risk.
The manifest description explicitly says the skill 'Generates PDF reports,' suggesting PDF output is part of the implemented behavior. However, the report generation section documents only Markdown and HTML output formats, creating a direct mismatch between the advertised capability and the described behavior in the skill file.
The skill stores audit data and configuration, including API-key-related settings, in a persistent workspace but does not prominently warn users about retention or sensitivity. In multi-tenant or shared-agent environments, silent persistence can expose site data, reports, or configuration details to later sessions or other components with filesystem access.
Telling users to set an environment variable pointing to the service-account key is a common configuration pattern, but without any warning it may encourage insecure handling of credential paths and associated secrets in shell history, process environments, shared profiles, or deployment configs. In combination with the previous step, it normalizes credential use without teaching safe storage and access controls.
The code creates and writes a report file under a workspace directory, which is a file-write operation covered by the warning requirement for code files. Although the script prints the report path after writing, there is no warning, confirmation, or pre-action disclosure before the write occurs, and the write behavior is not explained in comments beyond the high-level audit description.
The manifest describes technical SEO checks and site performance monitoring, which justifies fetching the target site and related SEO resources like robots.txt and sitemap.xml. However, this script additionally inspects the local environment for PAGESPEED_API_KEY and uses it to access Google's PageSpeed Insights API, introducing credential use and dependency on a third-party service that is not explicitly stated in the skill description or this script's documentation.
The script persists tracking results to a timestamped JSON file under the user's workspace, but the code provides no prior warning in usage text, comments, or prompts that keyword queries and ranking results will be stored locally. Because this is a file write involving user-provided keywords and site data, it meets the code-file warning criterion.