Back to skill

Security audit

Gaokao Volunteer Research

Security checks for vulnerabilities and agentic risk

Overview

This Gaokao research skill is coherent overall, but its helper script can fetch arbitrary URLs and save unbounded content, so it should be reviewed before installation.

Use this skill only with tightly scoped network and write permissions. Run the snapshot helper only for trusted official HTTPS sources, avoid third-party or user-supplied URLs unless manually checked first, and keep outputs in a dedicated research directory because raw downloaded content and metadata are persisted.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gaokao_toolkit.py:91
Finding

Unrestricted URL Retrieval Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/gaokao_toolkit.py, lines 91-98
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: Medium

python
def fetch_snapshot(args: argparse.Namespace) -> None:
    out_dir = Path(args.out)
    out_dir.mkdir(parents=True, exist_ok=True)
    req = urllib.request.Request(args.url, headers={"User-Agent": "gaokao-volunteer-research/0.3"})
    with urllib.request.urlopen(req, timeout=args.timeout) as resp:
        body = resp.read()
        content_type = resp.headers.get("content-type", "")

Technical Analysis

The snapshot command passes the user-controlled args.url directly to urllib.request.urlopen. The implementation does not:

  • Restrict requests to HTTPS.
  • Enforce an allowlist of official education or government domains.
  • Reject loopback, private, link-local, multicast, or reserved IP addresses.
  • Revalidate the destination after DNS resolution.
  • Validate redirect targets.
  • Prevent access to cloud metadata endpoints or local administrative services.

The source policy recommends official sources, but this is a documentation-level control and is not enforced by the executable implementation. Consequently, anyone capable of influencing the snapshot URL can use the Agent's network position to request resources that may not be reachable from the attacker's own system.

Attack Path

  1. An attacker presents a malicious URL as an admissions policy, score table, or university charter source.
  2. The Agent invokes:
    bash
    python3 scripts/gaokao_toolkit.py snapshot --url ATTACKER_CONTROLLED_URL ...
    
  3. The supplied URL points directly to an internal service, loopback interface, private address, or metadata endpoint, or redirects to one.
  4. urlopen sends the request using the Agent host's network identity and reachability.
  5. The response is read and saved as a snapshot in the selected research directory.

...[truncated 600 chars]

Remediation
View remediation

Remediation Suggestions

  • Permit only https URLs by default and reject unsupported schemes.
  • Resolve the destination hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6.
  • Repeat destination validation after every redirect and limit the number of redirects.
  • Consider allowlisting recognized government, examination-authority, CHSI, and university domains.
  • Require explicit user confirmation or an administrative override for destinations outside the allowlist.
  • Protect against DNS rebinding by connecting only to the validated address while preserving correct TLS hostname verification.
  • Record rejected destinations and validation reasons in structured audit output.
  • Apply network-level egress controls as defense in depth, especially blocking cloud metadata and internal management networks.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gaokao_toolkit.py:94
Finding

Unbounded Snapshot Download Can Exhaust Memory and Disk Resources

Content
View full analysis

Vulnerability Details

File Location: scripts/gaokao_toolkit.py, lines 94-109
Vulnerability Type: Uncontrolled Resource Consumption
Risk Level: Medium

python
    req = urllib.request.Request(args.url, headers={"User-Agent": "gaokao-volunteer-research/0.3"})
    with urllib.request.urlopen(req, timeout=args.timeout) as resp:
        body = resp.read()
        content_type = resp.headers.get("content-type", "")
        final_url = resp.geturl()
        status = resp.status

    sha = hashlib.sha256(body).hexdigest()
    stamp = time.strftime("%Y%m%d-%H%M%S")
    name = slugify(args.source_name or urllib.parse.urlparse(final_url).netloc)
    ext = infer_extension(final_url, content_type)
    raw_path = out_dir / f"{stamp}-{name}{ext}"
    raw_path.write_bytes(body)

Technical Analysis

The snapshot implementation calls resp.read() without a byte limit, loading the complete remote response into process memory. It does not inspect or enforce a maximum Content-Length, stream the response through bounded chunks, or impose a cumulative download quota.

The configured timeout limits blocking network operations but does not establish a maximum response size. A server that continuously sends data can therefore keep the operation active while causing steadily increasing memory consumption. If the response completes, the entire body is also written to disk.

Attack Path

  1. An attacker supplies a URL that returns an extremely large body or a continuous data stream.
  2. The Agent invokes the snapshot command for the purported research source.
  3. resp.read() continues buffering data without an upper bound.
  4. The Python process consumes increasing amounts of memory and may be terminated by the operating system.
  5. If the download completes, write_bytes stores the complete response, potentially consuming substantial disk capacity.
  6. Repeated requests can amplify resource consumption ...[truncated 463 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a conservative maximum snapshot size appropriate for policy documents and admissions data.
  • Reject responses whose declared Content-Length exceeds that limit.
  • Stream responses in fixed-size chunks instead of calling resp.read() without a bound.
  • Track the cumulative number of bytes and terminate the request immediately when the limit is exceeded.
  • Calculate the SHA-256 digest incrementally while streaming.
  • Write to a temporary file and atomically rename it only after successful completion and validation.
  • Delete partial files when a timeout, size violation, or network error occurs.
  • Enforce per-run download quotas and maximum request counts.
  • Apply process-level memory, disk, and execution-time limits as defense in depth.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (18)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill explicitly instructs use of file output, network-based verification, and local tooling, but it does not declare any permissions or allowed-tools scope. That creates a governance gap: an agent may use broader file and network capabilities than reviewers or policy enforcement expect, increasing the risk of unintended data access, writes outside the intended workspace, or unbounded external requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file’s natural-language instructions are entirely Chinese and do not indicate that users may choose another language or that the skill is intentionally limited to Chinese-speaking users. Under the language/locale policy rule, forcing a specific language without user opt-in is a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file contains natural-language instructions and examples exclusively in Chinese, with no indication that users may choose another language or locale. Under the policy, forcing a specific language without user opt-in is a reportable natural-language policy concern unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

标题和全文均以中文撰写,且没有说明该技能仅面向中文用户或特定地区合规场景,也未提供语言/locale 选择。根据规则,强制单一语言而无用户 opt-in 属于自然语言政策风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The snapshot command downloads remote content from a user-supplied URL and writes both the raw response body and metadata to disk. While these actions are central to the function, this file does not include a confirmation prompt, user-facing warning, or explanatory comment/docstring near the operation to disclose the data transfer and persistence behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file’s headings and field labels are entirely in Chinese, which implies the skill/template is intended to operate in a fixed language. Under the policy, forcing a specific language without user opt-in or a documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The entire template is written in Chinese and provides no indication that users may choose another language or locale. Under the policy rule for natural-language constraints, this can be a language/locale policy violation because it imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire markdown content is written in Chinese and presents the skill output format and behavior only in that language, with no indication that users may choose another language or that the skill is limited to a Chinese-language/regional context. This can violate language/locale policy when a skill implicitly forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file is entirely written in Chinese and presents the brief as if that language is required, with no indication that users may choose another language. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The entry states that a Chinese README.md was added, which may imply the skill documentation is being provided in a specific language. In this file there is no indication that users are offered a language choice or that the Chinese-only documentation is justified by a region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The markdown specifies 'README.md: 中文使用说明', which imposes a specific language requirement in the skill's natural-language instructions. Under the policy, locale or language constraints should either be optional or clearly justified; here no user choice or explicit justification is given.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The JSON values for source names, authority names, provinces, and notes are entirely in Chinese, with no indication that language selection is optional or configurable. Under the policy for natural-language violations, this constitutes a locale/language constraint that is not presented as opt-in or explicitly justified in the file itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file’s natural-language content is entirely in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. Under the language/locale policy rule, forcing a specific language without opt-in can be a policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The http_check helper issues GET requests to supplied source URLs and is used by the index verify command to contact external sites. The file does not provide a visible warning, prompt, or explanatory note near this behavior to inform users that running verification will make network requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file's natural-language instructions and labels are entirely in Chinese, and there is no indication that users may opt into another language or that the template is restricted to a justified Chinese-language context. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file uses Chinese throughout, and there is no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-language or region-specific audience. Under the policy rule for language or locale constraints, forcing a specific language without opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown content is entirely in Chinese and provides no indication that the user can choose another language or that the locale restriction is intentional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file's user-facing content consists entirely of Chinese column headers and source descriptions. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.