Back to skill

Security audit

site analyzing tools

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does the advertised website/network analysis, but it automatically profiles the user's own network and has unsafe external lookup code that could be abused.

Review before installing. Use this only for targets you are authorized to probe, avoid sensitive internal domains or customer IPs, and consider disabling or fixing the first-run environment probe, plaintext HTTP lookups, and unrestricted robots redirects before using it in a managed or private network.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/00_probe_env.sh:16
Finding
Arbitrary Python Code Injection Through Untrusted HTTP Geolocation Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/00_probe_env.sh`, lines 16-20 and 34-51 **Vulnerability Type**: Untrusted data interpolation into executable Python source **Risk Level**: High ### Vulnerable Code ```bash # Local public IP MY_IP=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || \ curl -s --max-time 5 http://ip-api.com/json 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('query',''))" 2>/dev/null) # Public IP attribution IP_INFO=$(curl -s --max-time 5 "http://ip-api.com/json/${MY_IP}" 2>/dev/null) ``` ```bash COUNTRY=$(echo "$IP_INFO" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('country','unknown'))" 2>/dev/null) CITY=$(echo "$IP_INFO" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('city','unknown'))" 2>/dev/null) ISP=$(echo "$IP_INFO" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('isp','unknown'))" 2>/dev/null) AS=$(echo "$IP_INFO" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('as','unknown'))" 2>/dev/null) python3 -c " import json data = { 'my_ip': '$MY_IP', 'country': '$COUNTRY', 'city': '$CITY', 'isp': '$ISP', 'as': '$AS', 'default_dns': '$DEFAULT_DNS'.strip(','), 'tools': { 'dig': '$DIG_OK' == 'true', 'traceroute': '$TRACEROUTE_OK' == 'true', 'ping': '$PING_OK' == 'true', 'whois': '$WHOIS_OK' == 'true' } } print(json.dumps(data, ensure_ascii=False, indent=2)) " | tee "$ENV_FILE" ``` ### Technical Analysis The script retrieves IP attribution data from `ip-api.com` over unencrypted HTTP. Values such as country, city, ISP, and autonomous-system information are then inserted directly into a string passed to `python3 -c`. Shell quoting does not make these values safe inside the generated Python program. An attacker able to alter the HTTP response can include quotes, commas, and Python expressions in a JSON string. After extraction, that string becomes executable ...[truncated 1746 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use HTTPS for every external API request and fail closed if transport security cannot be established. 2. Do not interpolate network-derived or command-derived values into Python source code. 3. Pass the complete JSON response to a fixed Python program through standard input and construct the output object entirely within that program. 4. If shell-to-Python transfer is unavoidable, use environment variables or command-line arguments and treat them strictly as data. 5. Enable strict shell behavior such as `set -euo pipefail`, validate API response status, and reject malformed or unexpectedly large responses. 6. A safe design would resemble: ```bash curl --fail --silent --show-error --max-time 5 \ "https://ip-api.com/json/${MY_IP}" | python3 -c ' import json import sys source = json.load(sys.stdin) data = { "country": source.get("country", "unknown"), "city": source.get("city", "unknown"), "isp": source.get("isp", "unknown"), "as": source.get("as", "unknown"), } json.dump(data, sys.stdout, ensure_ascii=False, indent=2) ' ``` 7. Ensure the selected API actually supports authenticated HTTPS on the intended plan; otherwise replace it with a provider that does. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/06_robots.py:14
Finding
Server-Side Request Forgery Through Unrestricted robots.txt Retrieval and Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/06_robots.py`, lines 14-30; duplicated in `sub/robots/06_robots.py`, lines 14-30 **Vulnerability Type**: Server-Side Request Forgery **Risk Level**: Medium ### Vulnerable Code ```python def fetch_robots(domain): """Try both HTTPS and HTTP.""" # Normalize input if not domain.startswith("http"): urls_to_try = [f"https://{domain}/robots.txt", f"http://{domain}/robots.txt"] else: parsed = urlparse(domain) base = f"{parsed.scheme}://{parsed.netloc}" urls_to_try = [f"{base}/robots.txt"] for url in urls_to_try: try: r = requests.get(url, headers=HEADERS, timeout=10, allow_redirects=True) return { "url": url, "final_url": r.url, "status_code": r.status_code, "content_type": r.headers.get("Content-Type", ""), "content_length": len(r.content), "text": r.text if r.status_code == 200 else None, "redirect_chain": [resp.url for resp in r.history] if r.history else [], } ``` ### Technical Analysis The function accepts a user-controlled domain or URL and performs an outbound request without restricting the destination to public Internet addresses. Loopback, private, link-local, reserved, and cloud metadata addresses are not rejected. The request also enables redirects through `allow_redirects=True`. Consequently, even if an initial hostname resolves to a public address, a public endpoint can redirect the client to an internal address. There is no validation of each redirect destination, no DNS rebinding protection, and no response-size limit. The fetched body is retained in the returned result when the response status is 200 and is parsed as robots.txt. The command-line display does not print the full body directly, but status, final URL, redirect history, parsed rules, sitemap values, and returned Python ...[truncated 1829 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept only explicit `http` and `https` schemes. 2. Resolve the hostname before connecting and reject every non-global address, including loopback, private, link-local, multicast, reserved, unspecified, and cloud metadata ranges. 3. Disable automatic redirects. Process redirects manually and repeat scheme, hostname, port, and resolved-address validation for every hop. 4. Pin the validated address for the connection or use a transport that prevents DNS rebinding between validation and connection. 5. Restrict destination ports to an allowlist such as 80 and 443 unless another port is explicitly required. 6. Block credentials in URLs and normalize internationalized hostnames before validation. 7. Set a small maximum number of redirects and stream the response with a strict byte limit. 8. Do not retain or return the raw response body unless the caller explicitly requests it. 9. Apply the same fix to both: - `scripts/06_robots.py` - `sub/robots/06_robots.py` 10. Consider requiring explicit user confirmation before accessing literal IP addresses or non-publicly resolvable hostnames. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/00_probe_env.sh:4
Finding
Network Environment Profile Stored Without Explicitly Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/00_probe_env.sh`, lines 4 and 39-53 **Vulnerability Type**: Insecure local storage permissions **Risk Level**: Low ### Vulnerable Code ```bash ENV_FILE="$HOME/.site-analyzer-env.json" ``` ```bash python3 -c " import json data = { 'my_ip': '$MY_IP', 'country': '$COUNTRY', 'city': '$CITY', 'isp': '$ISP', 'as': '$AS', 'default_dns': '$DEFAULT_DNS'.strip(','), 'tools': { 'dig': '$DIG_OK' == 'true', 'traceroute': '$TRACEROUTE_OK' == 'true', 'ping': '$PING_OK' == 'true', 'whois': '$WHOIS_OK' == 'true' } } print(json.dumps(data, ensure_ascii=False, indent=2)) " | tee "$ENV_FILE" echo "[env] Saved to $ENV_FILE" >&2 ``` ### Technical Analysis The script persists the invoking host’s public IP address, approximate location, ISP, configured DNS servers, and installed network-tool status in a predictable file under the user’s home directory. The file is created through `tee` without setting a restrictive umask or explicitly assigning mode `0600`. Its effective permissions therefore depend on the caller’s existing umask. Under a common `022` umask, a newly created file can be readable by other local users. Persisting a baseline environment is consistent with the Skill’s declared functionality, but unrestricted local visibility is not necessary for that purpose. The storage operation should follow least-privilege principles. ### Attack Path 1. A user runs the Skill for the first time, causing `00_probe_env.sh` to create `~/.site-analyzer-env.json`. 2. The user’s umask permits group or world read access. 3. Another local account reads the predictable file path. 4. The other account obtains the user’s public network identity, approximate location, ISP, DNS configuration, and information about installed reconnaissance tools. ### Impact Assessment This issue does not provide code execution or elevated privileges. It may disclose host reconnaissance information to other local ...[truncated 329 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set a restrictive umask before creating the file: ```bash umask 077 ``` 2. Create the destination with mode `0600` and verify its ownership before writing. 3. Write to a securely created temporary file in the same directory, apply mode `0600`, and atomically rename it into place. 4. Avoid `tee` for sensitive state unless permissions are established before opening the destination. 5. Minimize retained data. Store only fields that are required for later comparisons. 6. Document the persistent file and provide an option to disable environment profiling or remove the stored profile. ]]>
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (45)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a broad website/network profiling capability covering infrastructure location, ownership, network quality, routing, and robots policy. The supplied code chunk does not implement those functions. It is a narrow DNS query utility: it queries multiple DNS resolvers for A/AAAA records, optionally via DoH fallback, and summarizes returned IPs/CNAMEs/TTLs. While DNS lookup could be a supporting component of a larger site analysis tool, this code alone materially underdelivers relative to the declared purpose and lacks most of the advertised capabilities. Therefore the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明描述的是一个“站点综合分析工具”,覆盖站点画像中的多项能力;而当前代码片段实际只是一个批量IP归属查询脚本,核心功能限于通过两个外部IP信息服务查询并合并地理位置、组织和ASN等元数据。虽然这与声明中的“ISP/ASN归属、位置”部分有部分重合,但缺失了声明中的大部分关键能力,尤其是域名处理、GeoDNS/CDN检测、traceroute、延迟探测、robots策略和本机网络基线探测。因此该代码与声明存在明显的功能性不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a broad site profiling tool with multiple network-measurement and policy-analysis capabilities. The supplied code chunk does not perform those functions. It simply invokes the external 'whois' utility, parses registrar/domain and IP allocation metadata, and outputs selected fields. While WHOIS data may sometimes contain organization or country information relevant to ownership, that is far narrower than the claimed full site analysis, network path, CDN/GeoDNS, latency, robots, or local baseline detection features. Therefore the code's actual behavior is materially narrower than the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a broad site profiling tool covering hosting location, ISP/ASN, GeoDNS/CDN detection, traceroute, latency, and robots policy. The supplied code does only one narrow subtask: DNS resolution across several resolvers with UDP/DoH fallback, collecting A/AAAA/CNAME records and TTLs. While DNS results could support later higher-level analysis, none of the major claimed capabilities are implemented in this code chunk. Therefore the description does not accurately represent what this code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a broad 'site comprehensive analysis' capability covering domain/IP deployment analysis, network quality/path diagnostics, CDN/GeoDNS detection, robots.txt analysis, and first-run local network baseline probing. The supplied code does not implement those features. Instead, it only accepts IP inputs, skips private IPs, calls two external IP intelligence APIs (ip-api.com and ipinfo.io), merges the responses, and outputs basic attribution/location fields. While ISP/ASN/location overlap partially with the description, the primary scope is much narrower and lacks most of the advertised functionality. Therefore the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
声明描述的是一个“站点综合分析”能力集合,覆盖网络路径、时延、CDN/GeoDNS、robots 策略、本机网络基线等多项功能;而提供的代码块实际只实现了 whois 查询与结构化字段提取。这与声明的主要用途存在明显差异:代码既没有进行网络探测,也没有访问 robots.txt、执行 traceroute/ping、检测 CDN/GeoDNS,或自动分析本机网络环境。虽然 whois 结果中的组织、国家、CIDR 等字段可为归属分析提供部分线索,但不足以支撑声明中的完整“机房位置、ISP/ASN、网络质量、robots 策略”等综合分析能力。因此应判定为描述与实际行为不匹配。

External Script Fetching

High
Category
Supply Chain
Content
# 本机出口 IP
MY_IP=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || \
        curl -s --max-time 5 http://ip-api.com/json 2>/dev/null | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('query',''))" 2>/dev/null)

# 出口 IP 归属
IP_INFO=$(curl -s --max-time 5 "http://ip-api.com/json/${MY_IP}" 2>/dev/null)
Confidence
90% confidence
Finding
This finding is not truly 'external script fetching' in the sense of downloading and executing remote code, but it does perform insecure HTTP requests to a third-party geolocation API and consumes the response to drive later logic. Using plain HTTP allows tampering or surveillance by a network attacker, which can falsify detected IP/location data and expose sensitive network-environment details; the skill context makes this more concerning because it is meant to profile network infrastructure and runs automatically on first use.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
env_file = os.path.expanduser("~/.site-analyzer-env.json")
    if not os.path.exists(env_file):
        print("[setup] First run: probing network environment...", file=sys.stderr)
        os.system(f"bash {os.path.join(SCRIPT_DIR, '00_probe_env.sh')}")
    try:
        with open(env_file) as f:
            return json.load(f)
Confidence
93% confidence
Finding
The script automatically invokes a shell via os.system() on first run, which expands the attack surface because shell execution is less controlled than direct subprocess invocation and inherits the host environment. Even though the script path is derived from the local package directory rather than direct user input, this still causes implicit code execution on the analyst's machine and could be abused if the local skill files are tampered with or installed from an untrusted source.

Missing User Warnings

High
Confidence
99% confidence
Finding
The call to ip-api uses plain HTTP, so queried IP addresses and returned metadata travel without transport encryption and can be observed or modified by network intermediaries. Because this skill is specifically used for analyzing domains/IPs and network posture, leaking targets over cleartext can expose sensitive investigation activity and allow tampering with geolocation/ASN results.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises and orchestrates shell and network-capable scripts but does not declare any explicit tool scope such as permissions or allowed-tools. That increases the chance an agent executes network probes, shell commands, traceroute, ping, or local environment inspection without clear least-privilege boundaries or user visibility.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that first use automatically probes the local network environment and writes a baseline file under the user's home directory, but this behavior is not surfaced as a clear warning in the description. Silent local network inspection and persistent state creation can expose sensitive environment data, surprise users, and create privacy/compliance issues, especially in an agent setting where users may not expect host reconnaissance.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script automatically contacts third-party IP lookup services and discloses the host's public IP and related network metadata during a local environment probe, with only a generic status message and no meaningful consent or privacy warning. In this skill's context, the behavior is somewhat related to the advertised functionality, but doing it automatically on first use and persisting the result increases the privacy risk because it leaks operator/environment information to external services unnecessarily.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
When UDP DNS queries return empty, the script automatically sends the queried domain to external DoH providers including Google and Cloudflare. That can leak sensitive internal or user-supplied hostnames to third parties without explicit runtime consent, which is especially risky for an analysis tool that may be used on private infrastructure targets.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script sends user-supplied IP addresses to third-party services (ip-api.com over HTTP and ipinfo.io over HTTPS) without any explicit warning, consent flow, or privacy notice. In this skill’s context, users may analyze internal, customer, or sensitive infrastructure IPs, so silent disclosure to external providers can leak operationally sensitive metadata; the use of plain HTTP for one provider further increases exposure because requests can be intercepted or modified in transit.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This file includes natural-language descriptions and runtime messages in Chinese, but it does not indicate that the skill is region-specific or provide any opt-in for language selection. That can violate language/locale policy requirements when skills must not force a specific language on users by default.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
On first run, the skill automatically probes the local host environment by executing a bundled shell script, which performs local-side actions unrelated to merely formatting output. In a skill context, automatic host inspection is sensitive because it collects environmental data and runs code on the user's machine without a separate trust boundary or explicit opt-in.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code only prints a brief setup message and then immediately executes the probe script, which does not constitute meaningful informed consent for local environment inspection. Users may not realize the skill will run local commands and gather host/network metadata, making the behavior risky in managed or sensitive environments.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill automatically performs WHOIS, robots.txt retrieval, traceroute, and ping against the supplied target, generating observable network traffic to external systems. In a security-analysis tool this behavior is expected, but without explicit warning or confirmation it can still create legal, policy, privacy, or operational risk when users analyze third-party assets from sensitive networks.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def dig_with_ttl(domain, dns_server, record_type="A"):
    """用 dig 查询,返回带 TTL 的记录列表"""
    try:
        result = subprocess.run(
            ["dig", f"@{dns_server}", domain, record_type,
             "+noall", "+answer", "+time=3", "+tries=1"],
            capture_output=True, text=True, timeout=8
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def dig_with_ttl(domain, dns_server, record_type="A"):
    """用 dig 查询,返回带 TTL 的记录列表"""
    try:
        result = subprocess.run(
            ["dig", f"@{dns_server}", domain, record_type,
             "+noall", "+answer", "+time=3", "+tries=1"],
            capture_output=True, text=True, timeout=8
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The file’s user-facing description and instructions are entirely in Chinese, including the manifest description and operational guidance. Under the stated policy, forcing a specific language without offering user choice is a natural-language policy violation unless clearly justified as region-specific, which is not documented here.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The call to ip-api uses plain HTTP, so queried IP addresses and returned metadata travel without transport encryption and can be observed or modified by network intermediaries. Because this skill is specifically used for analyzing domains/IPs and network posture, leaking targets over cleartext can expose sensitive investigation activity and allow tampering with geolocation/ASN results.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly relies on external services (ip-api.com and ipinfo.io) to resolve user-supplied IP addresses, but it does not warn users that their query data will be transmitted to third parties. This creates a privacy and data-handling risk, especially if users analyze sensitive internal, customer, or investigative IPs and assume processing is local.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def ping_icmp(host, count=5):
    """ICMP ping"""
    try:
        result = subprocess.run(
            ["ping", "-c", str(count), "-W", "3", host],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def ping_icmp(host, count=5):
    """ICMP ping"""
    try:
        result = subprocess.run(
            ["ping", "-c", str(count), "-W", "3", host],
            capture_output=True, text=True, timeout=30
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.