T09 · Insecure Skill Coding Practices
- Location
webpage_reader.py:124- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This webpage-reading skill is mostly coherent, but it can make privileged system changes and fetch arbitrary URLs with an unsandboxed browser during normal use.
Review before installing. Use this only in an isolated environment with no access to sensitive internal networks, metadata endpoints, or local services, and do not run it with sudo-capable privileges. Preinstall Chrome manually through a trusted admin process rather than allowing the skill to install packages at runtime.
webpage_reader.py:124Unrestricted URL Fetching Enables Server-Side Request Forgery
webpage_reader.py:128Headless Chrome Processes Untrusted Pages with Its Sandbox Disabled
webpage_reader.py:78Normal Skill Execution Can Trigger Privileged System Package Installation
The README states that Chrome may be installed automatically, but it does not clearly warn users that running the skill can modify the host system by installing software and invoking package managers. In an agent-skill context, undocumented system modification is security-relevant because users may grant execution assuming the skill is read-only, which can lead to unexpected package installation and trust-boundary violations.
The README explicitly advertises automatic Chrome installation and webpage downloading, which implies both system modification and outbound network access, but it does not clearly warn users about those behaviors before use. In a skill context, undisclosed package installation and network retrieval increase the risk of unexpected changes to the host and accidental use in restricted or sensitive environments.
The skill documentation describes downloading and analyzing webpages but does not clearly warn users that arbitrary external URLs will be contacted, causing network requests to be sent to third-party sites. In an agent/skill context, this can lead to unintended data disclosure, SSRF-like access to internal resources, or privacy risks if users provide sensitive or internal URLs without understanding the network impact.
The documentation notes that Chrome may be automatically installed, but it does not sufficiently emphasize that this changes the local system by installing software and potentially invoking package managers with elevated privileges. In an agent environment, automatic dependency installation increases supply-chain and system-integrity risk, especially if users do not expect software installation as part of normal skill execution.
The documentation claims the skill only downloads webpage content, but the implementation also installs Chrome and invokes system package managers. This mismatch is security-relevant because it conceals host-modifying behavior from reviewers and users, undermining informed consent and making dangerous side effects easier to smuggle into agent workflows.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
return False
else:
# For macOS and Linux, use which command
result = subprocess.run(
['which', 'google-chrome'] if platform.system() != 'Darwin' else ['which', 'chrome'],
capture_output=True,
text=True
This code performs software installation as a side effect of a webpage-reading skill, which exceeds the declared functionality and modifies the host environment. Even with fixed arguments, auto-installing software can introduce unreviewed system changes, supply-chain exposure, and unexpected privilege escalation paths depending on how the skill is executed.
elif system == 'Darwin': # macOS
# macOS installation using Homebrew
try:
subprocess.run(['brew', 'install', 'google-chrome'], check=True)
return True
except subprocess.CalledProcessError:
logger.error("Homebrew not found. Please install Homebrew first or manually install Chrome.")
Running 'sudo apt-get update' from a content-processing skill causes privileged system modification without interactive confirmation or clear operator consent. In an agent context, this is dangerous because a simple request to read a webpage can unexpectedly trigger privileged package-manager activity and broaden the attack surface through repository trust and dependency changes.
distro = platform.dist()[0].lower() if hasattr(platform, 'dist') else 'unknown'
if 'ubuntu' in distro or 'debian' in distro:
subprocess.run(['sudo', 'apt-get', 'update'], check=True)
subprocess.run(['sudo', 'apt-get', 'install', '-y', 'google-chrome-stable'], check=True)
return True
elif 'fedora' in distro or 'centos' in distro or 'rhel' in distro:
Automatic package installation via sudo without explicit warning or approval is a genuine security issue in an agent skill. It can perform privileged changes on the host merely because a user asked to read a webpage, violating least surprise and enabling dangerous environment drift or abuse if the skill is invoked in sensitive systems.
This call attempts to install Chrome system-wide with sudo, which is a high-risk side effect for a webpage downloader. It can change the host state, pull packages from external repositories, and may execute with elevated privileges in environments where the agent already has broad access.
if 'ubuntu' in distro or 'debian' in distro:
subprocess.run(['sudo', 'apt-get', 'update'], check=True)
subprocess.run(['sudo', 'apt-get', 'install', '-y', 'google-chrome-stable'], check=True)
return True
elif 'fedora' in distro or 'centos' in distro or 'rhel' in distro:
subprocess.run(['sudo', 'dnf', 'install', '-y', 'google-chrome-stable'], check=True)
This privileged package installation on RPM-based systems has the same risk profile as the apt-based path: unexpected host modification, supply-chain exposure, and possible privilege misuse. The danger is amplified because the skill's stated purpose does not justify package-manager execution.
subprocess.run(['sudo', 'apt-get', 'install', '-y', 'google-chrome-stable'], check=True)
return True
elif 'fedora' in distro or 'centos' in distro or 'rhel' in distro:
subprocess.run(['sudo', 'dnf', 'install', '-y', 'google-chrome-stable'], check=True)
return True
else:
logger.error("Unsupported Linux distribution. Please manually install Chrome.")
This subprocess call launches a full headless browser against an attacker-controlled URL, which creates meaningful risk beyond a normal HTTP fetch. A remote page can trigger browser-level exploitation, internal network access/SSRF-like behavior from the host, and excessive resource consumption; the use of '--no-sandbox' materially increases the impact of any browser compromise.
logger.info(f"Running Chrome command: {' '.join(chrome_cmd)}")
# Execute the command and capture output
result = subprocess.run(
chrome_cmd,
capture_output=True,
text=True,
The main function is described as webpage processing, but it can trigger system-wide dependency installation as part of normal execution. In an agent skill, this hidden side effect is dangerous because downstream orchestrators may treat it as a read-only capability when it actually performs administrative changes.
文档内容全部以中文呈现,没有说明这是面向特定中文用户群体,也没有提供其他语言选项或用户可选择语言的提示。按照语言/locale政策,若强制单一语言且无明确限定或用户选择,可能构成自然语言策略问题。
The README describes downloading and analyzing arbitrary webpages but does not clearly warn that the skill will make outbound network requests and retrieve remote content. In an agent environment, this can expose user IP, trigger access to sensitive/internal URLs if misused, and create privacy or SSRF-like risk if operators assume the skill is local-only.
整个技能文档仅以中文呈现,未说明这是面向特定中文用户群的区域性技能,也未提供语言选择或英文替代。根据语言/区域政策,若技能对语言有实际约束,应提供用户选择或明确且合理的限制说明。
The manifest explicitly states that the skill downloads webpage content and returns that content, but it does not provide any user-facing warning about outbound network access, what remote data is fetched, or that fetched content may be transmitted back into the agent workflow. This is a real transparency and consent issue: users may invoke the skill without understanding that arbitrary URLs can be contacted and remote content ingested, which can expose internal browsing targets, sensitive query parameters, or untrusted prompt-bearing content.
The download function launches Chrome headlessly against the supplied URL, which causes external network access and transmission of request metadata such as IP, user agent, and possibly ambient browser behavior. The code states it downloads webpage content, but it does not present a specific warning or confirmation around contacting third-party sites.
No suspicious patterns detected.