Back to skill

Security audit

Dataset Search

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent dataset-search purpose, but it needs review because it can send detailed briefs to many external services and, with approval, download arbitrary URLs without strong safeguards.

Install only if you are comfortable with dataset queries and structured brief contents being sent to external catalog providers. Use --offline or a narrow --source list for sensitive work, avoid --url and untrusted --from-results files, and review any dry-run plan carefully before using --yes.

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)

other

Warning
Location
scripts/dataset_search.py:738
Finding

Dataset Briefs Are Transmitted to Multiple External Services by Default

Content
View full analysis
dict[str, Any]: if not path: return {} with open(path, "r", encoding="utf-8") as f: value = json.load(f) if not isinstance(value, dict): raise SystemExit("--brief must point to a JSON object") return value def build_query(args: argparse.Namespace, brief: dict[str, Any]) -> str: parts: list[str] = [] if args.query: parts.append(args.query) for key in ("question", "domain", "task", "geography", "period", "granularity", "modality", "format", "license"): value = brief.get(key) if isinstance(value, str): parts.append(value) for key in ("must_have", "keywords", "entities"): values = brief.get(key) if isinstance(values, list): parts.extend(str(v) for v in values) if args.region: parts.append(args.region) profile = PROFILES.get(args.profile or "general", PROFILES["general"]) parts.extend(profile.get("terms", [])) query = " ".join(p for p in parts if p) query = re.sub(r"\s+", " ", query).strip() if not query: raise SystemExit("Provide QUERY or --brief with enough fields to build a query") return query ``` The assembled query is subsequently sent to each selected source: ```python def make_search_payload(args: argparse.Namespace) -> dict[str, Any]: brief = load_brief(args.brief) query = build_query(args, brief) sources = select_sources(args.source, args.profile, brief) client = HttpClient(args.timeout) all_results: list[SearchResult] = [] statuses: list[dict[str, Any]] = [] for source in sources: results, status = search_source(source, query, args.limit, client, args.offline) statuses.append(status) ``` ### Technical Analysis The script ...[truncated 2222 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dataset_search.py:1486
Finding

Unrestricted HTTP Downloader Permits Server-Side Request Forgery and Unbounded File Retrieval

Content
View full analysis
dict[str, Any]: data = json.loads(Path(path).read_text(encoding="utf-8")) results = data.get("results") if not isinstance(results, list): raise SystemExit("Result file does not contain a results list") if index < 0 or index >= len(results): raise SystemExit(f"--index must be between 0 and {len(results) - 1}") return results[index] def download_url(url: str, output_dir: Path) -> Path: output_dir.mkdir(parents=True, exist_ok=True) parsed = urllib.parse.urlparse(url) name = os.path.basename(parsed.path.rstrip("/")) or safe_slug(url) if "." not in name: name += ".data" target = output_dir / name req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT}) with urllib.request.urlopen(req, timeout=DEFAULT_TIMEOUT) as resp: with open(target, "wb") as f: shutil.copyfileobj(resp, f) return target def build_download_plan(result: dict[str, Any], output_dir: Path) -> list[dict[str, Any]]: source = result.get("source") result_id = result.get("id") downloads = result.get("downloads") or {} plan: list[dict[str, Any]] = [] commands = downloads.get("commands") or [] urls = downloads.get("urls") or [] for command in commands: if isinstance(command, str) and command.startswith(("kaggle ", "huggingface-cli ")): command = command.replace("$OUTPUT_DIR", str(output_dir)) plan.append({"type": "command", "command": command}) for url in urls: if isinstance(url, str) and url.startswith(("http://", "https://")): plan.append({"type": "url", "url": url}) ``` Execution occurs after the user supplies `--yes`: ```python if not args.yes: print(json. ...[truncated 3614 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The download command accepts arbitrary user-supplied URLs and fetches them directly to local storage, making the tool a generic remote file retriever rather than a constrained dataset helper. This can be abused for SSRF-like access to internal HTTP endpoints, retrieval of unexpected or malicious payloads, or large-file denial of service if run in a privileged or network-reachable environment.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes Python scripts that can perform network access, shell out to external CLIs, and write files, yet the manifest does not declare any explicit tool scope or permission boundaries. That makes the skill harder to sandbox and review, and increases the chance an agent may grant broader-than-necessary capabilities during execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation guidance is very broad and could cause the skill to trigger on many ordinary data-related requests, including cases where networked dataset discovery or download is unnecessary. Over-broad triggering increases the chance of unnecessary exposure to external content, shell-driven helpers, and file/network operations in contexts that did not need this skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 210)May include surrounding context.

python
access="api/browser/doi",
        notes="Scientific datasets, articles, figures, and supplementary files.",
        adapter="figshare",
        api_url="https://api.figshare.com/v2/articles/search",
    ),
    "data-gov": Source(
        id="data-gov",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 1067)May include surrounding context.

python
access="api/browser/doi",
        notes="Scientific datasets, articles, figures, and supplementary files.",
        adapter="figshare",
        api_url="https://api.figshare.com/v2/articles/search",
    ),
    "data-gov": Source(
        id="data-gov",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 227)May include surrounding context.

python
id="nasa",
        name="NASA Open Data",
        categories=("science", "space", "earth", "socrata"),
        homepage="https://data.nasa.gov/",
        search_url="https://data.nasa.gov/browse?q={query}",
        access="api/browser",
        notes="NASA open data catalog. Also check Earthdata and NASA POWER for specialized access.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 228)May include surrounding context.

python
id="nasa",
        name="NASA Open Data",
        categories=("science", "space", "earth", "socrata"),
        homepage="https://data.nasa.gov/",
        search_url="https://data.nasa.gov/browse?q={query}",
        access="api/browser",
        notes="NASA open data catalog. Also check Earthdata and NASA POWER for specialized access.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 232)May include surrounding context.

python
access="api/browser",
        notes="NASA open data catalog. Also check Earthdata and NASA POWER for specialized access.",
        adapter="socrata",
        api_url="https://api.us.socrata.com/api/catalog/v1",
        search_context="data.nasa.gov",
    ),
    "harvard-dataverse": Source(

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 347)May include surrounding context.

python
access="api/browser",
        notes="NASA open data catalog. Also check Earthdata and NASA POWER for specialized access.",
        adapter="socrata",
        api_url="https://api.us.socrata.com/api/catalog/v1",
        search_context="data.nasa.gov",
    ),
    "harvard-dataverse": Source(

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 255)May include surrounding context.

python
access="api/browser",
        notes="Biodiversity occurrence and checklist datasets with DOI-backed downloads.",
        adapter="gbif",
        api_url="https://api.gbif.org/v1/dataset/search",
    ),
    "aws-open-data": Source(
        id="aws-open-data",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 297)May include surrounding context.

python
id="world-bank",
        name="World Bank Open Data",
        categories=("economics", "development", "statistics"),
        homepage="https://data.worldbank.org/",
        search_url="https://datacatalog.worldbank.org/search/dataset?query={query}",
        access="api/browser/csv",
        notes="Economic, social, education, health, energy, and country indicators.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 324)May include surrounding context.

python
id="un-data",
        name="UN Data",
        categories=("statistics", "global", "government"),
        homepage="https://data.un.org/",
        search_url="https://data.un.org/Search.aspx?q={query}",
        access="browser/api",
        notes="United Nations statistical databases across global development topics.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 325)May include surrounding context.

python
id="un-data",
        name="UN Data",
        categories=("statistics", "global", "government"),
        homepage="https://data.un.org/",
        search_url="https://data.un.org/Search.aspx?q={query}",
        access="browser/api",
        notes="United Nations statistical databases across global development topics.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 342)May include surrounding context.

python
id="cdc",
        name="CDC Open Data",
        categories=("health", "government", "us", "socrata"),
        homepage="https://data.cdc.gov/",
        search_url="https://data.cdc.gov/browse?q={query}",
        access="api/browser",
        notes="US public health datasets hosted on Socrata.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 343)May include surrounding context.

python
id="cdc",
        name="CDC Open Data",
        categories=("health", "government", "us", "socrata"),
        homepage="https://data.cdc.gov/",
        search_url="https://data.cdc.gov/browse?q={query}",
        access="api/browser",
        notes="US public health datasets hosted on Socrata.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 363)May include surrounding context.

python
id="imf",
        name="IMF Data",
        categories=("economics", "finance", "statistics", "global"),
        homepage="https://data.imf.org/",
        search_url="https://www.imf.org/en/Search#q={query}%20data",
        access="api/browser",
        notes="Macroeconomic and financial datasets from the International Monetary Fund.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 372)May include surrounding context.

python
id="data-europa",
        name="data.europa.eu",
        categories=("government", "eu", "open-data"),
        homepage="https://data.europa.eu/",
        search_url="https://data.europa.eu/data/datasets?query={query}",
        access="api/browser",
        notes="European Union and member-state open data catalog.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 373)May include surrounding context.

python
id="data-europa",
        name="data.europa.eu",
        categories=("government", "eu", "open-data"),
        homepage="https://data.europa.eu/",
        search_url="https://data.europa.eu/data/datasets?query={query}",
        access="api/browser",
        notes="European Union and member-state open data catalog.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 489)May include surrounding context.

python
id="data-world",
        name="data.world",
        categories=("catalog", "collaboration", "sql"),
        homepage="https://data.world/",
        search_url="https://data.world/search?context=community&q={query}&type=resources",
        access="api/browser/sql",
        notes="Community and organizational datasets with SQL/API access for many resources.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 490)May include surrounding context.

python
id="data-world",
        name="data.world",
        categories=("catalog", "collaboration", "sql"),
        homepage="https://data.world/",
        search_url="https://data.world/search?context=community&q={query}&type=resources",
        access="api/browser/sql",
        notes="Community and organizational datasets with SQL/API access for many resources.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 507)May include surrounding context.

python
id="mendeley-data",
        name="Mendeley Data",
        categories=("science", "doi", "research"),
        homepage="https://data.mendeley.com/",
        search_url="https://data.mendeley.com/research-data/?search={query}",
        access="browser/doi",
        notes="Research datasets and supplementary data with DOI metadata.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 508)May include surrounding context.

python
id="mendeley-data",
        name="Mendeley Data",
        categories=("science", "doi", "research"),
        homepage="https://data.mendeley.com/",
        search_url="https://data.mendeley.com/research-data/?search={query}",
        access="browser/doi",
        notes="Research datasets and supplementary data with DOI metadata.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 534)May include surrounding context.

python
id="nasdaq-data-link",
        name="Nasdaq Data Link",
        categories=("finance", "economics", "market-data"),
        homepage="https://data.nasdaq.com/",
        search_url="https://data.nasdaq.com/search?query={query}",
        access="api/browser/csv",
        notes="Financial and alternative datasets. Many downloads require an API key or subscription.",

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 535)May include surrounding context.

python
id="nasdaq-data-link",
        name="Nasdaq Data Link",
        categories=("finance", "economics", "market-data"),
        homepage="https://data.nasdaq.com/",
        search_url="https://data.nasdaq.com/search?query={query}",
        access="api/browser/csv",
        notes="Financial and alternative datasets. Many downloads require an API key or subscription.",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dataset_search.py (reported line 878)May include surrounding context.

python
if not command_exists("kaggle"):
        return []
    cmd = ["kaggle", "datasets", "list", "-s", query, "--csv"]
    proc = subprocess.run(cmd, text=True, capture_output=True, timeout=30, check=False)
    if proc.returncode != 0:
        raise RuntimeError((proc.stderr or proc.stdout or "kaggle CLI failed").strip())
    text = proc.stdout.strip()

Static analysis

No suspicious patterns detected.