T09 · Insecure Skill Coding Practices
- Location
scripts/lib/url-safety.mjs:106- Finding
DNS Rebinding Can Bypass SSRF Address Validation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent web-search tool, but its network safety boundary has verified gaps that could expose private network targets or API credentials in some configurations.
Review this before installing in environments with access to internal HTTP services, cloud metadata, or valuable provider API keys. Use it only with trusted target URLs and trusted gateway configuration, avoid sensitive search text unless you accept provider transmission, and prefer disabling custom gateway overrides or running it in a network-restricted sandbox.
scripts/lib/url-safety.mjs:106DNS Rebinding Can Bypass SSRF Address Validation
scripts/engines/perplexity.mjs:207Custom Perplexity Gateway URLs Can Receive API Credentials Without Transport or Destination Validation
Referenced artifact was not completely inspected
- `capabilities.mjs`
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
});
const rules = parseRobotsTxt(snapshot.body);
cache.set(origin, rules);
return rules;
} catch {
cache.set(origin, []);
return [];
Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.
const BLOCKED_HOSTNAMES = new Set([
"localhost",
"metadata.google.internal",
"metadata.google.internal.",
]);
Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.
const BLOCKED_HOSTNAMES = new Set([
"localhost",
"metadata.google.internal",
"metadata.google.internal.",
]);
The README explicitly promotes live web search, extraction, crawling, and mapping, but it does not clearly warn users that running these commands will make outbound network requests and may transmit user queries, target URLs, and retrieved content to third-party services or remote sites. In an agent skill context, this omission is security-relevant because agents may execute search and crawl actions on sensitive prompts or internal URLs, creating unintended data exposure or SSRF-like access to internal resources if users are not alerted to the network boundary.
The skill exposes code-backed behavior with access to environment variables and external network-capable runtime actions, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates a transparency and least-privilege problem: a host agent or reviewer cannot easily constrain what the skill is allowed to access, increasing the risk of unintended secret exposure or broader execution than expected.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import { requestText } from "../lib/http-client.mjs";
const API_URL = "https://api.search.brave.com/res/v1/web/search";
function normalizeCount(value, max = 20) {
const n = Number.parseInt(String(value ?? 5), 10);
This code sends the user's search query in outbound HTTP requests to an external service via both POST and GET paths. The file contains no confirmation prompt, logging, comment, or docstring warning that user-provided queries will be transmitted off-system.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
// Exa Search Engine - AI-native semantic search
// API docs: https://exa.ai/docs/reference/search
const SEARCH_URL = "https://api.exa.ai/search";
const CONTENTS_URL = "https://api.exa.ai/contents";
export function isAvailable() {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
// Exa Search Engine - AI-native semantic search
// API docs: https://exa.ai/docs/reference/search
const SEARCH_URL = "https://api.exa.ai/search";
const CONTENTS_URL = "https://api.exa.ai/contents";
export function isAvailable() {
The search and extract functions send user-provided query text and URL inputs to the external Exa service via HTTP requests. While the file contains technical comments and error handling, it does not include any confirmation prompt, user-facing log, or warning comment/docstring disclosing that user data is sent to a third-party API.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const NATIVE_API_URL = "https://api.perplexity.ai/v1/sonar";
const OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions";
const KILO_API_URL = "https://api.kilo.ai/api/gateway/chat/completions";
const DEFAULT_NATIVE_MODEL = "sonar-pro";
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const NATIVE_API_URL = "https://api.perplexity.ai/v1/sonar";
const OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions";
const KILO_API_URL = "https://api.kilo.ai/api/gateway/chat/completions";
const DEFAULT_NATIVE_MODEL = "sonar-pro";
const DEFAULT_GATEWAY_MODEL = "perplexity/sonar-pro";
const DEFAULT_OPENROUTER_MODEL = "perplexity/sonar";
The code unconditionally applies SEARXNG_LANGUAGE to every search request when the environment variable is set. This enforces a locale/language preference at runtime without exposing a user choice or documenting an opt-in mechanism, which matches the policy's language/locale violation criterion.
The code sends the full user query, along with optional domain filters and date constraints, to the third-party SerpAPI service via a GET request. In an agent-first search skill, queries may contain sensitive user or enterprise information, and there is no evidence here of consent, minimization, redaction, or disclosure before transmitting that data off-platform. The skill context increases risk because web-search agents are often used for research on internal projects, incidents, customers, or code, making accidental leakage to an external provider plausible.
This code sends the raw search query and related search parameters to Serper, a third-party external API, without any indication in this file of user consent, redaction, or warning. In an agent skill, queries may contain sensitive user prompts, internal URLs, company names, or other confidential context, so external transmission can create a privacy and data-handling risk even if the behavior is functionally intended.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
// Tavily Search Engine - AI-optimized search with full parameter support
// API docs: https://docs.tavily.com/documentation/api-reference/endpoint/search
const API_URL = "https://api.tavily.com/search";
const EXTRACT_URL = "https://api.tavily.com/extract";
export function isAvailable() {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
// Tavily Search Engine - AI-optimized search with full parameter support
// API docs: https://docs.tavily.com/documentation/api-reference/endpoint/search
const API_URL = "https://api.tavily.com/search";
const EXTRACT_URL = "https://api.tavily.com/extract";
export function isAvailable() {
The function sends the user-provided query and the Tavily API key to a third-party service via HTTP POST. In this file there is no confirmation prompt, user-facing warning, or explanatory comment disclosing that search terms are transmitted externally.
This code posts the provided URLs and API key to Tavily's extract endpoint, which is a network operation transmitting potentially sensitive user-supplied targets to a third party. The file contains no confirmation prompt, warning message, or comment that would disclose this behavior to users.
The default configuration sets crawl.respectRobotsTxt to false, meaning the crawler will ignore site owners' robots.txt restrictions unless explicitly overridden. In a web-search and site-crawl skill, this can cause unauthorized or policy-violating crawling of disallowed paths, increasing legal, compliance, and abuse risk at scale.
This code fans out a user query to one or more provider executors, which are external search backends, but there is no inline warning, prompt, or user-facing disclosure in this file. Because federated mode can expand a single request into multiple network transmissions, users may not realize their query is being sent to several providers.
The skill's purpose is web search and retrieval, so making network requests is expected. However, this helper adds subprocess execution by importing execFile and using it to run curl, which is a more powerful host capability than ordinary HTTP fetching and is not justified by the manifest description itself.
This module performs outbound network requests via both fetch and curl, and also invokes the curl subprocess, but the file contains no confirmation prompt, user-facing logging, or explanatory comment/docstring warning about those actions. Because these operations can transmit user or system data off-host, they meet the code-file missing-warning criterion.
This code materializes and exposes configured providers and available features, including baseline providers such as DuckDuckGo and Safe Fetch, which imply outbound network access. There is no confirmation prompt, logging, or inline disclosure here to indicate that user queries or fetched targets may be sent to external services when these providers are enabled.
Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal