Back to skill

Security audit

finddata.skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent FindData API helper, but it asks agents to collect API keys from chat and its Python client can send that key to a configurable API origin.

Only install this if you are comfortable sending your data questions to FindData and using a FindData API key. Do not paste the key into chat; prefer setting it through a trusted environment or secret manager. Also avoid setting FINDDATA_BASE_URL unless you fully trust the destination, because the client may send the API key there.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/finddata.py:23
Finding
API Key Exposure Through an Unrestricted Base URL## Vulnerability Details **File Location**: `scripts/finddata.py`, lines 23–31 and 38–42 **Vulnerability Type**: Credential disclosure through an attacker-controlled API origin **Risk Level**: Medium ### Vulnerable Code ```python def __init__( self, api_key: Optional[str] = None, base_url: Optional[str] = None, ): self.api_key = api_key or os.environ.get("FINDDATA_API_KEY", "") self.base_url = (base_url or os.environ.get("FINDDATA_BASE_URL", self.DEFAULT_BASE_URL)).rstrip("/") self.session = requests.Session() if self.api_key: self.session.headers["X-API-Key"] = self.api_key self.session.headers["Content-Type"] = "application/json" def query(self, question: str, strategy: str = "smart") -> dict: resp = self.session.post( f"{self.base_url}/query", json={"query": question, "strategy": strategy}, ) ``` The same credential-bearing session is also used by `catalog()` and `health()`: ```python def catalog(self) -> dict: """List all available data sources.""" resp = self.session.get(f"{self.base_url}/catalog") resp.raise_for_status() return resp.json() def health(self) -> dict: """Check API health status.""" resp = self.session.get(f"{self.base_url}/health") resp.raise_for_status() return resp.json() ``` ### Technical Analysis The client stores `X-API-Key` as a default session header while allowing the request origin to be selected through either the `base_url` constructor parameter or the `FINDDATA_BASE_URL` environment variable. It performs no scheme enforcement, hostname allowlisting, or explicit authorization check before forwarding the credential. Consequently, anyone who can influence client construction or the process environment can cause the API key to be transmitted to an arbitrary HTTP or HTTPS server. Allowing plaintext HTTP also permits interception by a network-positioned attacker. Because the header is configured on the shared session, the issue aff ...[truncated 1339 chars]
Remediation
## Remediation Suggestions 1. Restrict authenticated requests to an explicit HTTPS origin allowlist, such as `https://finddata.ai`. 2. Parse the URL and reject non-HTTPS schemes, embedded user information, malformed hosts, and unexpected ports. 3. Do not attach credentials as global session headers when requests may target configurable origins. Add `X-API-Key` only after validating each request URL. 4. If custom endpoints are required, make them an explicit opt-in and require separate credentials rather than reusing the production API key. 5. Disable cross-origin redirects for authenticated requests or validate every redirect target before forwarding authentication headers. 6. Treat `FINDDATA_BASE_URL` as security-sensitive configuration and prevent untrusted users from controlling the process environment. 7. Add tests confirming that credentials are never sent to plaintext, unapproved, or redirected origins.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/finddata.py:38
Finding
Unbounded Network Requests Can Block the Client Indefinitely## Vulnerability Details **File Location**: `scripts/finddata.py`, lines 38–57 **Vulnerability Type**: Missing network timeouts causing denial of service **Risk Level**: Low ### Vulnerable Code ```python resp = self.session.post( f"{self.base_url}/query", json={"query": question, "strategy": strategy}, ) resp.raise_for_status() return resp.json() def catalog(self) -> dict: """List all available data sources.""" resp = self.session.get(f"{self.base_url}/catalog") resp.raise_for_status() return resp.json() def health(self) -> dict: """Check API health status.""" resp = self.session.get(f"{self.base_url}/health") resp.raise_for_status() return resp.json() ``` ### Technical Analysis None of the `requests` calls specifies a timeout. The Requests library does not apply a default timeout, so connection establishment or response reads may wait indefinitely. A remote endpoint that accepts a connection but stalls before completing its response can retain the calling thread or worker for an unbounded period. The condition may also occur because of service degradation or network failure, without an active attacker. ### Attack Path 1. The client sends a request to the configured API endpoint. 2. The endpoint accepts the connection but deliberately or accidentally stops sending response data. 3. Because no connect or read timeout exists, the request remains blocked. 4. Repeated calls occupy additional threads, workers, or agent execution slots. 5. Available processing capacity may eventually be exhausted, degrading or denying service. If an attacker can also control `base_url`, exploitation is direct. Otherwise, exploitation requires control of, or a network position affecting, the configured service. ### Impact Assessment Exploitation can block the current worker indefinitely and may cause broader resource exhaustion when multiple requests accumulate. Affected assets include application availability, worker capacity, and a ...[truncated 195 chars]
Remediation
## Remediation Suggestions 1. Set explicit connect and read timeouts for every request, for example: ```python timeout = (5, 30) resp = self.session.post( f"{self.base_url}/query", json={"query": question, "strategy": strategy}, timeout=timeout, ) ``` 2. Apply equivalent timeout settings to `catalog()` and `health()`. 3. Catch `requests.Timeout` and return or raise a controlled, application-specific error. 4. Use bounded retries only for transient failures, with exponential backoff and jitter. 5. Limit total retry duration and concurrent outstanding requests so retries cannot amplify resource exhaustion. 6. Add tests using a deliberately slow endpoint to verify that all methods terminate within the configured deadline.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## Usage

```bash
curl -s -X POST https://finddata.ai/api/query \
  -H "X-API-Key: $FINDDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "Apple stock price"}'
Confidence
60% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly instructs the agent to extract a user-provided API key from the conversation and transmit it to an external service, but it provides no privacy warning, consent boundary, or safer credential-handling mechanism. This creates a clear risk of sensitive secret handling through natural-language input, which can lead to inadvertent disclosure, logging, or misuse of the key.

Ssd 3

Medium
Confidence
98% confidence
Finding
Telling the agent to extract a key from the user's message and use it as an HTTP header establishes a natural-language secret exfiltration pattern. Even if intended for convenience, it normalizes harvesting credentials from chat content, increasing the chance that secrets are retained in logs, reused in the wrong context, or sent to an attacker-controlled or unverified endpoint.

Ssd 3

Medium
Confidence
97% confidence
Finding
The repeated instruction to pull keys from user text reinforces unsafe secret-collection behavior and makes accidental leakage more likely. Repetition in setup guidance increases the odds that downstream agents or users will treat chat as an acceptable channel for transmitting credentials, which is dangerous in systems where prompts may be stored, inspected, or replayed.

External Transmission

Medium
Category
Data Exfiltration
Content
## Usage

```bash
curl -s -X POST https://finddata.ai/api/query \
  -H "X-API-Key: $FINDDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "Apple stock price"}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code sends the user's natural-language question to a remote service via HTTP and may include the X-API-Key header configured earlier, but the query method provides no warning, confirmation, or explicit disclosure that user input is transmitted off-system. The surrounding docstrings describe functionality but do not clearly warn about network transmission or credential use.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The constructor automatically loads an API key from an environment variable and attaches it to outbound requests, which is sensitive credential handling. While this is common behavior for API clients, the file does not explicitly warn users that credentials are being sourced from the environment and transmitted to the service.

Static analysis

No suspicious patterns detected.