Back to skill

Security audit

SEO DataForSEO

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform DataForSEO keyword research as advertised, but it needs review because credentials, default saved results, unpinned dependencies, and loose result-file helpers create avoidable exposure.

Install only if you are comfortable sending keyword, domain, location, and trend queries to DataForSEO and storing the returned data locally by default. Use a dedicated DataForSEO account or limited credentials, install dependencies in an isolated environment, consider pinning package versions, and avoid using the result-loading helpers on arbitrary paths.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Open-Ended Dependency Versions Permit Unreviewed Supply-Chain Updates

Content
View full analysis
=1.0.34 python-dotenv>=1.0.0 ``` The installation script installs these unresolved dependency versions directly: ```bash #!/bin/bash pip install -r "$(dirname "$0")/requirements.txt" ``` ### Technical Analysis Both dependencies use open-ended minimum-version constraints. Consequently, each installation may retrieve a different future release without an upper bound, integrity hash, or lock file. Those future releases have not necessarily been reviewed with the Skill. This is particularly sensitive for `dataforseo-client`, because the package is imported into the application and receives the configured DataForSEO credentials. A malicious or compromised future version could execute code during installation or import and access environment variables, local files, or network resources with the privileges of the user running the Skill. No evidence was found that the currently named packages are typosquatted or malicious. The vulnerability is the uncontrolled trust placed in all future releases satisfying the lower-bound constraints. ### Attack Path 1. An attacker compromises the publishing account, distribution channel, or a future release of one of the permitted dependencies. 2. The attacker publishes a version higher than the specified minimum. 3. A user follows the documented setup procedure and runs `scripts/setup.sh` or the equivalent `pip install -r scripts/requirements.txt`. 4. `pip` resolves and installs the attacker-controlled release because it satisfies the open-ended constraint. 5. Malicious package code executes during an applicable installation or import stage. 6. The malicious code operates with the installing user's privileges and may read the DataForSEO credentials from the environment ...[truncated 596 chars]
Remediation
View remediation
python-dotenv== ``` 2. Generate and commit a reproducible lock file using a tool such as `pip-tools`, Poetry, or uv. 3. Include cryptographic hashes for every direct and transitive dependency and install with hash enforcement: ```bash pip install --require-hashes -r requirements.txt ``` 4. Review release notes and package provenance before updating any pinned version. 5. Perform dependency vulnerability and package-integrity scanning in CI. 6. Install dependencies in an isolated virtual environment rather than the system Python environment. 7. Consider using a trusted internal package mirror and restricting package installation to approved artifacts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/core/storage.py:42
Finding

Public Storage Helpers Do Not Enforce the Results Directory Boundary

Content
View full analysis
Dict[str, Any]: """Load a previously saved result.""" with open(filepath, 'r', encoding='utf-8') as f: return json.load(f) ``` ```python base_dir = settings.RESULTS_DIR if category: base_dir = base_dir / category if not base_dir.exists(): return [] pattern = f"*{operation}*" if operation else "*" files = sorted(base_dir.glob(f"**/{pattern}.json"), reverse=True) return files[:limit] ``` ### Technical Analysis `pathlib.Path` does not automatically constrain joined paths to the original base directory. If `category` is absolute, the absolute component replaces `settings.RESULTS_DIR`. Traversal components such as `../` can also resolve outside the intended results director ...[truncated 2520 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes a feature-complete SEO research capability powered by the DataForSEO API. However, the supplied code chunk contains only a setup shell script that installs dependencies. This is a materially different primary purpose from the declared behavior, and none of the described analysis capabilities are evidenced in the code shown. While dependency installation can be a supporting detail, the only available code does not implement or demonstrate the declared functionality, so the description is not accurately represented by this code chunk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The skill explicitly relies on credentials stored in a .env file and instructs the runtime to import and execute code that will use them, which creates a credential access path. In an agent setting, any skill that reads secrets from environment-backed storage is high risk unless access is tightly scoped, because compromised or overly broad code could exfiltrate or misuse the API credentials.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
---
name: seo-dataforseo
description: "SEO keyword research using the DataForSEO API. Perform keyword analysis, YouTube keyword research, competitor analysis, SERP analysis, and trend tracking. Use when the user asks to: research keywords, analyze search volume/CPC/competition, find keyword suggestions, check keyword difficulty, analyze competitors, get trending topics, do YouTube SEO research, or optimize landing page keywords. Requires a DataForSEO API account and credentials in .env file."
---

# SEO Keyword Research (DataForSEO)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config/settings.py (reported line 6)May include surrounding context.

python
from pathlib import Path
from dotenv import load_dotenv

# Load environment variables from .env file in current working directory
load_dotenv()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config/settings.py (reported line 38)May include surrounding context.

python
from pathlib import Path
from dotenv import load_dotenv

# Load environment variables from .env file in current working directory
load_dotenv()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documents capabilities that require network access, reading environment variables, and writing files, but it does not declare any explicit tool or permission scope. That makes the operational boundary unclear and increases the risk that an agent will grant broader access than users expect, especially since the workflow includes credential use and automatic persistence to disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill states that all results are automatically saved as timestamped JSON files, but this persistence is not surfaced as an upfront warning in the main description or consent flow. SEO research data can include user-supplied keywords, competitor domains, and derived analysis that may be sensitive in business contexts, so silent retention creates privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The API reference does not warn that inputs such as keywords, search queries, and target domains are sent to the external DataForSEO service. Users of an agent skill may reasonably assume local processing, so this omission can cause unintentional disclosure of confidential marketing plans, customer interests, or competitor intelligence to a third party.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation shows save=True as the default for many functions, which means keyword queries, target domains, and returned SEO data may be written to local JSON files without an explicit opt-in or warning. In an agent setting, this can create unintended persistence of potentially sensitive business research data, increasing exposure through local disk access, logs, backups, or later tool reuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This function sends user-supplied keywords to the external DataForSEO API and, by default, persists the returned data locally via save_result without any explicit consent, warning, or privacy boundary in the function contract. In an SEO research skill, users may provide sensitive campaign terms, unreleased product names, or client data, so silent disclosure to a third party and local retention creates a real confidentiality and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function transmits a target domain to an external API and saves the resulting analysis locally without surfacing that side effect at the call boundary. Even though domain names are often public, in this skill context they may reveal client relationships, competitive intelligence targets, or confidential audit activity, making undisclosed sharing and persistence a legitimate privacy and operational-security issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This function submits keyword lists to a remote advertising-traffic endpoint and saves results locally by default, again without explicit notice or consent in the function behavior. Advertising keywords can contain commercially sensitive strategy data, and default persistence increases exposure by leaving a local artifact that may be accessible beyond the immediate task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Seed keywords are forwarded to a third-party API and the resulting keyword ideas are persisted locally without an explicit warning, which creates a clear data disclosure and retention issue. In an SEO tool this is especially relevant because seed terms may reflect unreleased products, campaigns, or proprietary market research, so the skill context makes the finding more—not less—concerning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This function sends user-supplied keywords to a third-party API and persists returned data locally by default, but provides no notice, consent mechanism, or privacy control at the call boundary. In an agent skill context, users may reasonably assume inputs stay within the assistant, so silent external transmission and storage can expose sensitive business plans, campaign terms, or proprietary research.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Seed keywords are transmitted to an external service and the resulting dataset is saved locally by default without any user-facing warning. Because keyword suggestions often reflect confidential marketing strategy, this creates a privacy and data-governance risk even if the code is functioning as intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Keyword idea generation sends potentially sensitive seed terms to a third party and stores the response without clear disclosure. In this SEO skill, such inputs are central to the user's competitive and content strategy, so undisclosed sharing is more dangerous than in a purely public-data workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The related-keyword lookup transmits the user's query terms externally and persists the analysis locally by default with no notice. This can leak sensitive campaign, product, or research interests and may violate user expectations or organizational policy around third-party data sharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Bulk keyword difficulty analysis submits entire keyword lists to a third-party service and saves outputs by default without informing the user. Bulk lists may reveal full campaign roadmaps or customer-intent research, increasing confidentiality and compliance risk if sent or stored silently.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Historical search volume retrieval sends user keywords to DataForSEO and stores returned trend data locally without explicit disclosure. Even though the returned metrics are not inherently dangerous, the submitted keyword set itself may contain confidential strategic intent, making silent transmission and persistence a privacy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Search-intent classification transmits user keyword lists to a third-party API and persists the output by default with no clear warning. In an agent workflow, this hidden data flow can surprise users and expose commercially sensitive search targets or user research to external systems and local storage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Domain analysis sends a target domain to an external API and saves the resulting data locally without clearly informing users. While domains are often public, the fact that a user is investigating a competitor or internal property can itself be sensitive business intelligence, so undisclosed sharing still presents risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Competitor discovery sends the user's keyword set to an external service and stores the resulting competitor analysis by default without explicit user disclosure. Because this directly reflects market strategy and competitive research, the skill context makes the silent sharing/storage notably more sensitive.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code sends the user-supplied keyword plus location and language metadata to an external DataForSEO SERP API. Although the functions are documented for developers, there is no confirmation prompt or user-facing warning in the code that search terms and contextual data are transmitted off-system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Search results are persisted by default, and the saved payload is likely associated with the user-provided keyword, which can contain sensitive business or personal search terms. Default persistence increases exposure through local storage, logs, backups, or later unauthorized access, especially because saving occurs automatically unless callers explicitly disable it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

These additional SERP functions transmit user queries to a third-party provider and save the returned data by default, extending the same unnecessary persistence risk across multiple endpoints. In an SEO tool, user queries can reveal confidential marketing plans, client names, or investigative interests, so default storage broadens the attack surface.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Google Maps queries often include location-sensitive searches such as nearby businesses or local intent terms, and the function both transmits and may persist that data without any protective guardrails in this module. Persisting such query-linked results can expose sensitive location interests if storage is later accessed improperly.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.