T09 · Insecure Skill Coding Practices
- Location
example_usage.js:59- Finding
Shell Command Injection Through User-Controlled Search Query
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This search skill is mostly purpose-aligned, but it needs review because it can automatically send searches to external providers and includes unsafe or under-scoped execution patterns.
Install only if you are comfortable with search queries leaving your environment and with the skill running local Python subprocesses. Avoid sensitive, internal, regulated, or credential-like searches; prefer explicit provider choice; and review or remove the sibling ddg-search execution and shell-command example before using it in an agent with broad filesystem or credential access.
example_usage.js:59Shell Command Injection Through User-Controlled Search Query
scripts/unified_search.py:51Unverified Execution of a Python Script From a Sibling Skill
requirements.txt:1Mutable and Misdeclared Third-Party Dependencies Create Supply-Chain Risk
The invocation examples are broad everyday phrases such as general search requests, which increases the chance the skill is triggered unintentionally in unrelated conversations. In an agent environment, overly generic triggers can cause unsolicited external queries, data leakage of user text to third-party services, and tool-selection hijacking.
The declared description promises a unified search capability with conditional routing across three providers based on query type/language. The supplied code does not do that. It only shows example usage for a Baidu search skill, including browser automation against baidu.com and execution of a local baidu_search.py script. There is no logic for detecting Chinese vs. English vs. crypto queries, and no calls to DuckDuckGo or CoinGecko. This is a material description-behavior mismatch, not just an incomplete implementation detail.
The declared description promises a unified search capability with conditional routing among Baidu, DuckDuckGo, and CoinGecko. However, the supplied code chunk only implements a Baidu-focused quick test utility: it validates dependencies, invokes scripts/baidu_search.py with a hardcoded Chinese query, and displays Baidu-specific usage guidance. There is no logic for language detection, crypto-topic detection, engine selection, DuckDuckGo access, or CoinGecko access. This is therefore a material description-behavior mismatch, not merely an implementation detail.
The declared description promises a unified search tool with query-type-based routing across three services: Baidu for Chinese, DuckDuckGo for English, and CoinGecko for crypto. The supplied code chunk contains only a Baidu search implementation. It constructs Baidu search URLs, performs requests to www.baidu.com, parses Baidu HTML for results, and returns those results. There is no logic to detect query language or topic, no calls to DuckDuckGo or CoinGecko, and no multi-engine orchestration. Therefore the actual behavior is materially narrower than the declared purpose, making this a clear description-behavior mismatch.
The declared description says the skill routes Chinese queries to Baidu, English queries to DuckDuckGo, and cryptocurrency queries to CoinGecko. The code only partially matches this: it does use CoinGecko for crypto-related queries and Baidu for general search, but there is no DuckDuckGo integration at all. Instead, it scrapes Bing as a backup source. Also, there is no language detection or explicit English-query routing; Baidu is attempted for every query, and Bing is used only if results are sparse. This is a material behavior mismatch with the declared purpose.
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
try:
# 使用UTF-8编码运行
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'utf-8'
result = subprocess.run(
The manifest states the unified-search skill routes English searches to DuckDuckGo, but this document repeatedly describes a multi-source implementation using Baidu, CoinGecko, and Bing instead. This is a semantic mismatch between the claimed behavior and the documented behavior of the skill.
The documentation promotes sending user queries to multiple third-party services (CoinGecko, Baidu, and Bing/DuckDuckGo) without warning that search terms and related metadata will leave the local environment. This creates a real privacy and data-handling risk, especially if users search for sensitive terms, credentials, internal project names, or regulated information.
The usage examples and later workflow description present normal search as '百度 + Bing' and fallback from Baidu to Bing. That behavior does not match the manifest's stated scope of using Baidu for Chinese, DuckDuckGo for English, and CoinGecko for cryptocurrency.
Hardwiring engine selection based on language or topic without user opt-in removes user control over where their query is sent. That matters because routing Chinese text to Baidu, English text to DuckDuckGo, or crypto queries to CoinGecko can have privacy, compliance, and trust implications depending on the user's expectations and environment.
The documentation says the '智能 Python 脚本' mode provides '百度 + Bing + CoinGecko' and later repeats '百度 + Bing 双保险'. This contradicts the stated skill purpose and manifest description, which define English search via DuckDuckGo rather than Bing, indicating the docs describe behavior outside the declared engine set.
Repeatedly describing mandatory language-driven routing without a default override increases the likelihood that queries are sent to unintended external providers. In this skill context, the danger is not code execution but privacy and policy risk from automatic disclosure of user queries to specific services.
The claim that users can 'just say it' implies ambiguous natural-language triggering without clear boundaries. In a tool-using agent, that can cause accidental activation and transmission of conversational content to external search providers without sufficiently explicit user intent.
The changelog for v1.5 states a fallback mechanism of '百度 → Bing → 浏览器', which diverges from the declared skill intent that English search should use DuckDuckGo and that the unified scope is Baidu, DuckDuckGo, and CoinGecko. This is an active documentation contradiction, not merely omitted detail.
The skill advertises and instructs use of shell commands, Python scripts, networked searches, and dependency installation, but it does not declare any explicit tool scope such as allowed-tools or permissions. That creates an authorization and review gap: an agent or user may invoke network and shell-capable actions without clear least-privilege boundaries or informed approval.
The skill routes user queries to third-party services but does not warn users that their input will be transmitted to Baidu, DuckDuckGo, or CoinGecko. This creates a real privacy and compliance risk because users may unknowingly disclose sensitive prompts, identifiers, or internal data to external providers.
The skill enforces language-based routing to different external providers without explicit user choice, which can silently alter the privacy, jurisdictional, and trust characteristics of the request. Automatic routing is especially risky in a search skill because users may not realize that merely changing language changes the destination and handling of their data.
The trigger phrase "搜索[查询内容]" is extremely broad and likely to fire on ordinary conversational requests, causing unintended activation of a skill that sends content to external services. In skill ecosystems, overbroad triggers can create prompt/intent hijacking, privacy leaks, and confusion about whether the assistant is acting locally or invoking third parties.
The manifest describes a unified search skill that routes Chinese queries to Baidu, English queries to DuckDuckGo, and cryptocurrency queries to CoinGecko. This file’s documentation and code only implement and describe Baidu-based search flows, including a Python script under a baidu-search directory, with no logic for English or crypto-specific engines.
This JavaScript file presents the skill entirely in Chinese, including its title, usage guidance, and console messages, with no indication that users may choose another language. The policy explicitly calls for flagging language or locale constraints when they are imposed without user opt-in or documented justification.
The module docstring says this is a 'Baidu Search' quick test script, and the rest of the file is dedicated to invoking only baidu_search.py. That directly conflicts with the manifest, which claims a unified search skill that routes Chinese to Baidu, English to DuckDuckGo, and crypto to CoinGecko.
The script hardcodes execution of scripts/baidu_search.py and uses a Chinese query for testing, with no logic for English searches or cryptocurrency lookups. For a skill described as unified search across Baidu, DuckDuckGo, and CoinGecko, this indicates the implemented/tested behavior is narrower than the declared manifest scope.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'utf-8'
result = subprocess.run(
[sys.executable, SCRIPT_PATH, test_query, "--format"],
capture_output=True,
text=True,
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
for dep in dependencies:
try:
__import__(dep)
print(f"[OK] {dep} 已安装")
except ImportError:
print(f"[ERROR] {dep} 未安装")
The usage output repeatedly tells users they are using a 'Baidu Search' skill and instructs them to run skills/baidu-search and scripts/baidu_search.py. This is active documentation that contradicts the manifest's claim of a unified multi-engine search capability.