Back to skill

Security audit

Web Search

Security checks for vulnerabilities and agentic risk

Overview

This web-search skill is mostly coherent, but it needs Review because its crawler can fetch arbitrary URLs from the host environment without network-scope safeguards.

Install only in an environment where outbound crawling is sandboxed away from localhost, private networks, cloud metadata endpoints, and sensitive internal services. Avoid sending secrets, private URLs, or confidential queries through it, and prefer pinned dependencies or a reviewed lockfile before production use.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/web_search.py:276
Finding
Server-Side Request Forgery Through Arbitrary URL Crawling<![CDATA[ ## Vulnerability Details **File Location**: `scripts/web_search.py:276-278`, with insufficient validation at `scripts/web_search.py:335-352` and the externally reachable call path at `scripts/web_search.py:475-481` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```python async def crawl_page_async(url: str) -> Dict[str, Any]: """Asynchronously crawl webpage content.""" if not HAS_CRAWL4AI: return { 'success': False, 'message': 'crawl4ai is not installed; unable to crawl webpages' } try: async with AsyncWebCrawler() as crawler: result = await crawler.arun(url=url) ``` The validation applied before reaching this sink is limited to the URL scheme and length: ```python def validate_url(url: str) -> tuple: """Validate URL.""" if not url: return False, 'URL cannot be empty' if not isinstance(url, str): return False, 'URL must be a string' url = url.strip() if len(url) == 0: return False, 'URL cannot be empty' if not url.startswith(('http://', 'https://')): return False, 'URL must begin with http:// or https://' if len(url) > 2000: return False, 'URL length cannot exceed 2000 characters' return True, '' ``` The crawl action passes the validated but otherwise unrestricted URL to the crawler: ```python elif action == 'crawl': url = kwargs.get('url', '') is_valid, error_msg = validate_url(url) if not is_valid: return {'success': False, 'message': error_msg} return crawl_page(url.strip()) ``` ### Technical Analysis The `crawl` action accepts an attacker-controlled HTTP or HTTPS URL and passes it to `AsyncWebCrawler.arun()`. Validation only confirms that the value is a string, uses an HTTP-based scheme, and is no longer than 2,000 characters. It does not reject: - IPv4 or IPv6 loopback destinations - RFC 1918 private networks - Lin ...[truncated 2008 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse URLs with a standards-compliant URL parser and allow only explicitly required schemes. 2. Resolve the hostname before connecting and reject every address classified as loopback, private, link-local, reserved, multicast, or unspecified for both IPv4 and IPv6. 3. Revalidate the resolved destination immediately before connection to reduce time-of-check/time-of-use and DNS-rebinding risks. 4. Disable redirects when possible. If redirects are required, validate the scheme, hostname, resolved addresses, and port of every redirect target before following it. 5. Prefer an explicit allowlist of approved external domains and ports instead of attempting to block known-dangerous ranges. 6. Block cloud metadata endpoints at both application and network layers. 7. Run the crawler in a network-isolated sandbox without access to internal networks, host services, or cloud metadata. 8. Apply request timeouts, response-size limits, concurrency limits, and rate limits to reduce scanning and denial-of-service abuse. 9. Add tests covering decimal, hexadecimal, octal, shortened, and IPv4-mapped IPv6 address representations, redirects, user-information URL syntax, and DNS rebinding scenarios. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:4
Finding
Unpinned Runtime Dependencies Create Supply-Chain and Reproducibility Risk<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:4-16`, consumed by `setup.py:14-15` and `setup.py:31` **Vulnerability Type**: Unpinned and Unverified Third-Party Dependencies **Risk Level**: Medium ### Vulnerable Code ```text # Package manager (recommended for fast installation) uv>=0.1.0 # HTTP requests requests>=2.28.0 # Baidu search library (no API key required) baidusearch>=1.0.3 # Web crawling library (deep search) crawl4ai>=0.8.0 # Playwright browser automation playwright>=1.40.0 ``` The open-ended requirements are passed directly to package installation: ```python with open("requirements.txt", "r", encoding="utf-8") as fh: requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")] ``` ```python install_requires=requirements, ``` ### Technical Analysis All dependencies use open-ended lower bounds and the project provides no reviewed lock file or artifact hashes. A new installation can therefore resolve to any future version that satisfies the minimum constraint. This prevents deterministic builds and means the code reviewed during this audit does not fully determine the code that will execute in deployment. Third-party packages can run code during installation, import, browser startup, and crawling operations. The dependency set includes browser automation and web-crawling components with broad network and local execution capabilities, increasing the impact of an unexpectedly compromised release. Including `uv` as a runtime dependency also unnecessarily expands the trusted computing base because it is described as an installation tool rather than functionality required by the Skill at runtime. ### Attack Path 1. A user installs the project using `pip install -e .` or another resolver. 2. `setup.py` reads the open-ended constraints from `requirements.txt`. 3. The resolver selects the newest available versions satisfying the minimum versions. 4. No lock file or cryptographic hash verif ...[truncated 1019 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin production dependencies to exact, reviewed versions. 2. Generate and commit a lock file appropriate to the deployment workflow. 3. Require cryptographic hashes for downloaded artifacts where supported. 4. Remove `uv` from runtime dependencies and document it only as an optional development or installation tool. 5. Separate runtime, development, and optional crawling/browser dependencies. 6. Perform controlled dependency updates through review and automated testing rather than resolving arbitrary future versions during deployment. 7. Use dependency vulnerability and provenance scanning in continuous integration. 8. Install packages from a trusted package index and restrict unapproved alternative indexes. 9. Build and deploy from an internal artifact repository or verified wheelhouse when stronger supply-chain controls are required. 10. Run installation and execution with least privilege and isolate browser and crawler components from sensitive files and networks. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description frames the skill as a general web search tool, but the documented actions also include arbitrary URL crawling and deep content extraction from result pages. That mismatch can mislead users and automated policy systems into granting broader network and data-extraction behavior than intended, increasing the risk of privacy leakage, SSRF-like internal fetches in permissive environments, or unauthorized content collection.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises executable script behavior with network access and likely local file-read capability via dependencies/runtime, but it does not declare any explicit tool scope or permissions boundary. This weakens reviewability and can cause hosts or users to invoke a skill with broader capabilities than they reasonably expect, especially when combined with crawling and browser automation.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
Imposing Chinese locale behavior in metadata/default behavior without clear opt-in can alter routing of searches and data exposure to region-specific providers, which may have different privacy, censorship, or compliance implications. While not inherently malicious, hidden locale assumptions can undermine user expectations and organizational policy controls.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation omits that user queries, clicked results, and target URLs are sent to third-party search engines and websites. This creates a real privacy and data-handling risk because users may submit sensitive prompts or internal URLs without understanding they will be disclosed externally.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
A fixed default region of 'cn-zh' can silently direct traffic and search content through Chinese-language/regional settings even when the user did not request that behavior. In security-sensitive settings, this may increase privacy, compliance, and result-integrity risks by changing where data is sent and what content is returned.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The request headers explicitly set Accept-Language to zh-CN/zh for Baidu, forcing a specific language/locale preference regardless of user choice. This is a natural-language policy concern because the code does not offer a locale option or obtain user opt-in for that language constraint.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The Bing request headers prioritize zh-CN/zh before English, which imposes a specific locale preference in search behavior. The file does not provide a user choice or explain a justified region-specific constraint, so this appears to violate the language/locale policy requirement.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The file exposes general-purpose page fetching and content extraction via crawl_page/crawl_page_async, which materially exceeds a search-only skill description. This capability can be used to retrieve arbitrary external content, increasing the skill’s data-access and network-exfiltration surface beyond what users and reviewers would reasonably expect from the declared functionality.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
Deep-search automatically visits returned URLs and extracts page content, moving from simple search into active browsing and scraping. That increases risk because user input is not only sent to search engines but also causes follow-on requests to third-party sites, potentially exposing browsing intent and pulling untrusted content into downstream workflows.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Search queries and crawl URLs are transmitted to external services (Baidu, DuckDuckGo, Bing, and potentially arbitrary result pages) without any visible user-facing disclosure in the code path. This creates a privacy risk because sensitive prompts, identifiers, or internal URLs supplied by users may be leaked to third parties or logged externally.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The exposed crawl action allows callers to fetch arbitrary HTTP(S) URLs, which is a broader network primitive than the advertised web-search function. In an agent environment, this can be abused to access unexpected endpoints, retrieve sensitive internal web resources if reachable, or proxy requests through the host running the skill.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This requirements file includes multiple natural-language comments only in Chinese, such as package descriptions and recommendations. For a general-purpose skill, forcing a specific language in user-facing or maintainer-facing text without opt-in or documented regional scope can violate language/locale policy expectations.

Unpinned Dependencies

Low
Category
Supply Chain
Content
# Web Search Skill Requirements

# 包管理器(推荐用于快速安装)
uv>=0.1.0

# HTTP请求
requests>=2.28.0
Confidence
92% confidence
Finding
Using an unpinned dependency range for uv means installations may resolve to different versions over time, including vulnerable or behavior-changing releases. This weakens supply-chain reproducibility and makes it harder to verify whether known advisories affect deployed environments.

Unverifiable Dependency: uv has 7 known advisory(ies) (GHSA-4gg8-gxpx-9rph (uv is vulnerable to arbitrary file write through entry point names); CVE-2025-54368 (uv allows ZIP payload obfuscation through parsing differentials); GHSA-pjjw-68hj-v9mw (uv vulnerable to arbitrary file deletion through RECORD entries) +4 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding
The manifest does not pin uv, and the package has multiple known advisories, including file write and deletion classes of issues. Because the resolved version is unknown, consumers cannot determine whether installation or execution may involve a vulnerable release.

Unpinned Dependencies

Low
Category
Supply Chain
Content
uv>=0.1.0

# HTTP请求
requests>=2.28.0

# 百度搜索库(无需API Key)
baidusearch>=1.0.3
Confidence
94% confidence
Finding
Using requests>=2.28.0 allows future installs to pull different versions, which can introduce known or newly disclosed vulnerabilities and inconsistent TLS or credential-handling behavior. In a web-search skill that performs outbound HTTP requests, this increases supply-chain and runtime risk.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); 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) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
Requests has known advisories, and without an exact version pin there is no assurance that deployed environments avoid affected releases. In a network-facing search skill, a vulnerable HTTP client can expose credentials, mishandle redirects, or weaken transport security expectations.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0

# 百度搜索库(无需API Key)
baidusearch>=1.0.3

# 网页抓取库(深度搜索)
crawl4ai>=0.8.0
Confidence
88% confidence
Finding
An unpinned baidusearch dependency makes builds non-reproducible and can silently introduce unsafe upstream changes. Because this skill relies on search-provider interaction, pulling an unexpected library version could affect request handling or scraping logic in security-relevant ways.

Unpinned Dependencies

Low
Category
Supply Chain
Content
baidusearch>=1.0.3

# 网页抓取库(深度搜索)
crawl4ai>=0.8.0

# Playwright 浏览器自动化
playwright>=1.40.0
Confidence
97% confidence
Finding
Allowing crawl4ai to float with >=0.8.0 is particularly risky because crawling frameworks often process untrusted remote content and may expose SSRF, file-write, or sandbox escape issues. The skill context makes this more dangerous because deep web crawling directly expands the attack surface to attacker-controlled pages and responses.

Unverifiable Dependency: crawl4ai has 16 known advisory(ies) (CVE-2026-57571 (Crawl4AI: Arbitrary file write (path traversal) in crawler downloads can lead to); CVE-2026-56260 (Crawl4AI: Multiple Docker API Vulnerabilities - File Write, SSRF, Auth Bypass, X); CVE-2025-28197 (Crawl4AI SSRF vulnerability) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
98% confidence
Finding
Crawl4AI is associated with advisories including SSRF and arbitrary file write classes, and the manifest leaves the installed version unspecified. In this skill, that is especially dangerous because web crawling inherently processes attacker-controlled URLs and content, amplifying the likelihood and impact of such flaws.

Unpinned Dependencies

Low
Category
Supply Chain
Content
crawl4ai>=0.8.0

# Playwright 浏览器自动化
playwright>=1.40.0
Confidence
95% confidence
Finding
An unpinned Playwright version can introduce browser automation and sandbox-related changes without review. Since browser automation executes and renders untrusted web content, version drift can materially change exposure to remote content, downloads, and automation vulnerabilities.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The function accepts a region parameter but defaults it to cn-zh and does not actually honor it, which can mislead users about how their requests will be localized or routed. In this skill context, that is a low-severity transparency/privacy issue because it may direct traffic and results toward a locale the user did not meaningfully choose.

Static analysis

No suspicious patterns detected.