Back to skill

Security audit

DuckDuckGo搜索服务

Security checks for vulnerabilities and agentic risk

Overview

This is advertised as a DuckDuckGo search skill, but it depends on a different third-party service and stores an API key locally.

Review carefully before installing. Only use it if you trust xiaobenyang.com with your search queries, fetched URLs, and XBY API key, and be aware that the key is stored in a local .env file in plaintext. The package should be corrected to align its name, docs, code, credential handling, and dependency pinning before broad use.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises and instructs use of capabilities including environment access, file reads/writes, and network operations, yet declares no permissions. This undermines user and platform trust boundaries because the skill can persist secrets, access local state, and make outbound requests without explicit upfront disclosure.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented purpose is a DuckDuckGo search/fetch service, but the behavior described includes persisting API keys locally, relying on a third-party upstream service, and exposing a more generic API-calling surface than users would expect. This mismatch is dangerous because users may provide credentials and allow network/data operations under a narrower trust assumption than the skill actually requires.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill documentation contains a clear purpose mismatch: it is presented as DuckDuckGo search, but examples and project naming reference a gaokao/high-school-admissions skill. Such inconsistency is a strong trust and supply-chain risk signal because it suggests copied, repurposed, or misdirecting instructions that can hide broader behavior than the user intended to authorize.

Intent-Code Divergence

Medium
Confidence
80% confidence
Finding
Saying 'code only calls APIs' conflicts with claims of webpage fetching and parsing, which are materially different capabilities with broader privacy and security implications. This inconsistency can mislead users and reviewers about the real data handling and network behavior of the skill.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The configuration module contains logic for an unrelated 'XBY/Gaokao' service, including handling and persistence of an API key, which conflicts with the declared DuckDuckGo search skill purpose. This mismatch is dangerous because it expands the trust boundary: a user enabling a search tool would not reasonably expect hidden credential-management behavior for a different remote service.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The code can write and update API credentials in a local .env file, which is beyond the direct need of a search/content-fetching skill and creates persistent credential storage on disk. This increases the risk of accidental exposure through backups, source control inclusion, shared workspaces, or later compromise of the host environment.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The docstring and configuration identify the module as a '小笨羊高考Skill' rather than a DuckDuckGo search service, indicating code reuse or hidden functionality inconsistent with the advertised capability. In skill ecosystems, this kind of intent mismatch is a serious trust and supply-chain concern because it may conceal undeclared network dependencies or credential flows.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill offers arbitrary webpage fetching/parsing without warning about privacy implications, external requests, or the possibility of retrieving sensitive/internal URLs if misused. In a search-and-fetch context, this makes the issue more dangerous because network access is core functionality and likely to be exercised frequently.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs the model to collect a user API key and save it, but does not warn the user that the credential will be persisted locally. This creates a consent and secret-handling risk because users may believe the key is used transiently when it is actually retained for future sessions.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The function persists an API key to .env without any visible warning, consent flow, or indication that secrets will be written to disk. Silent credential persistence is risky because users may assume the key is ephemeral while it remains recoverable from files, logs, backups, or misconfigured repositories.

Ssd 3

Medium
Confidence
96% confidence
Finding
Persisting a user-provided API key based on natural-language instructions creates a concrete data retention and exposure risk, especially when combined with file and environment access. If the local file is readable by other components or accidentally logged/synced, the credential can be exfiltrated and abused against the upstream service.

Ssd 3

Medium
Confidence
93% confidence
Finding
Instructing the model to directly display raw tool output can expose sensitive content returned by the upstream service or fetched webpages, including tokens, internal metadata, or unexpected personal data. This is especially risky in a network-enabled scraping skill because raw responses often contain more information than should be shown to end users.

Credential Access

High
Category
Privilege Escalation
Content
default_year: int = 2025

    def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")
Confidence
88% confidence
Finding
The code forcibly reads XBY_APIKEY directly from .env during post-initialization for an undeclared XBY/Gaokao service embedded in a DuckDuckGo skill. In this context, direct secret loading for an unrelated service is dangerous because it accesses local credentials outside the user’s reasonable expectation and broadens the blast radius of the skill.

Credential Access

High
Category
Privilege Escalation
Content
def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")
            for line in content.splitlines():
Confidence
88% confidence
Finding
Checking for and reading a local .env file to extract XBY_APIKEY gives this skill access to locally stored credentials for an unrelated service. In the context of a claimed DuckDuckGo search tool, that behavior is unexpected and increases supply-chain and secret-exposure risk even without explicit exfiltration shown here.

Credential Access

High
Category
Privilege Escalation
Content
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()
Confidence
90% confidence
Finding
This function is dedicated to saving an API key into a .env file, creating durable on-disk secret storage inside a skill that is supposed to provide web search capabilities. Persistent plaintext secret storage is dangerous because it can be exposed through file disclosure, backups, shared directories, or accidental repository commits.

Credential Access

High
Category
Privilege Escalation
Content
def set_api_key(api_key: str) -> bool:
    """设置API key并持久化到.env"""
    if not api_key or not api_key.strip():
        return False
    api_key = api_key.strip()
Confidence
89% confidence
Finding
The function explicitly advertises setting and persisting an API key to .env, which embeds secret-management behavior for an unrelated service into the skill. In this context, that is unsafe because it normalizes hidden credential storage and can cause users to unknowingly leave recoverable secrets on disk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
The dependency uses a lower-bound specifier instead of pinning to an exact version, which makes builds non-reproducible and can cause the environment to resolve to unexpectedly vulnerable or incompatible releases over time. In a network-search and content-fetching service, this increases supply-chain and operational risk because external HTTP functionality is central to the skill.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
Using an unpinned pydantic version allows future installs to pull different releases, which can introduce security fixes, regressions, or newly disclosed issues unpredictably. While not an exploit by itself, it weakens reproducibility and dependency governance.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
An unpinned pydantic-settings dependency permits uncontrolled version drift between installations, increasing the chance of pulling a problematic upstream release. This is a supply-chain hygiene issue rather than direct malicious code, but it still creates avoidable security and stability exposure.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
96% confidence
Finding
The unpinned python-dotenv dependency allows installation of whatever latest version satisfies the lower bound, reducing reproducibility and potentially introducing vulnerable releases. Because dotenv libraries often interact with environment and configuration files, uncontrolled upgrades can have outsized operational impact.

Known Vulnerable Dependency: requests==2.31.0 — 5 advisory(ies): CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func) +2 more

Medium
Category
Supply Chain
Confidence
92% confidence
Finding
The requirements permit installation of requests 2.31.0, which is associated with multiple advisories including credential leakage and request verification issues. Given this skill performs web search and content retrieval over untrusted remote URLs, a vulnerable HTTP client is more dangerous here because attackers may be able to influence request destinations or responses.

Known Vulnerable Dependency: python-dotenv==1.0.1 — 1 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via )

Low
Category
Supply Chain
Confidence
84% confidence
Finding
The dependency range includes python-dotenv 1.0.1, which has an advisory related to symlink following in set_key and possible arbitrary file overwrite. This is less central to a search service than the HTTP client issue, but it remains relevant if the skill writes or edits .env files in environments where local paths can be attacker-influenced.

Static analysis

No suspicious patterns detected.