Back to skill

Security audit

Kubernetes Encyclopedia

Security checks for vulnerabilities and agentic risk

Overview

This skill is a Kubernetes documentation and note-taking helper with disclosed local caching and no evidence of credential theft, persistence, or deceptive behavior.

Reasonable to install for Kubernetes work. Before use, be aware it may fetch official Kubernetes documentation and create a .Kubernetes-Encyclopedia directory in the current workspace. Do not put secrets or full access details in its notes. Treat cached docs as convenience copies, and prefer fixing redirect and response-size bounds in cache_doc.py before using it in tightly controlled network environments.

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/cache_doc.py:130
Finding
Redirect Destinations Bypass the Intended Network Allowlist## Vulnerability Details **File Location**: `scripts/cache_doc.py`, lines 130-134 **Vulnerability Type**: Redirect validation weakness **Risk Level**: Medium ### Vulnerable Code ```python def fetch_html(url: str) -> str: req = urllib.request.Request(url, headers={'User-Agent': USER_AGENT}) with urllib.request.urlopen(req, timeout=20) as resp: charset = resp.headers.get_content_charset() or 'utf-8' return resp.read().decode(charset, errors='replace') ``` ### Technical Analysis The script validates the user-supplied URL before calling `fetch_html`, restricting its initial scheme and hostname to HTTPS and `kubernetes.io`. However, `urllib.request.urlopen()` follows HTTP redirects automatically, and the final response URL is not passed through `validate_url()`. Consequently, an initially permitted Kubernetes documentation URL could redirect to a different hostname, scheme, explicit port, or direct IP address. This creates a limited server-side request forgery and network-policy bypass condition. Content retrieved from the unapproved destination would also be written beneath a cache path representing official Kubernetes documentation, potentially causing untrusted content to be treated as authoritative. Exploitation depends on an accepted `https://kubernetes.io/docs/...` endpoint returning a redirect to an unapproved destination. The audit found no credential, kubeconfig, environment-variable, local-note, or cluster-state transmission in the request. ### Attack Path 1. An attacker identifies or causes an allowed `https://kubernetes.io/docs/...` endpoint to return an HTTP redirect. 2. The initial URL passes `validate_url()`. 3. `urllib.request.urlopen()` automatically follows the redirect. 4. The redirect target is accessed without reapplying the hostname, scheme, port, direct-IP, path, or query restrictions. 5. The response from the unapproved destination is parsed and stored under the trusted ...[truncated 741 chars]
Remediation
## Remediation Suggestions - Disable automatic redirect handling and process redirects explicitly. - Apply `validate_url()` to every redirect destination before following it. - Resolve relative `Location` headers against the current validated URL and then validate the resulting absolute URL. - Reject redirects to non-HTTPS schemes, hosts other than `kubernetes.io`, explicit ports, direct IP addresses, user-information components, or paths outside `/docs`. - After opening the response, validate `resp.geturl()` as a defense-in-depth control before reading or caching content. - Set a small maximum redirect count and reject redirect loops. - Record the final validated source URL in cache metadata so the stored provenance is accurate.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/cache_doc.py:130
Finding
Unbounded Network Response Can Exhaust Memory and Disk Resources## Vulnerability Details **File Location**: `scripts/cache_doc.py`, lines 130-134 **Vulnerability Type**: Unbounded response processing **Risk Level**: Low ### Vulnerable Code ```python def fetch_html(url: str) -> str: req = urllib.request.Request(url, headers={'User-Agent': USER_AGENT}) with urllib.request.urlopen(req, timeout=20) as resp: charset = resp.headers.get_content_charset() or 'utf-8' return resp.read().decode(charset, errors='replace') ``` ### Technical Analysis Calling `resp.read()` without a size argument buffers the entire HTTP response in memory. The 20-second timeout limits certain network delays but does not impose a maximum response size. The script also does not validate `Content-Length`, enforce a streamed byte limit, or restrict accepted media types. A very large response could therefore consume substantial memory during download and decoding. Additional copies or structures may be created during HTML parsing, normalization, content assembly, and writing to disk. The redirect-validation weakness broadens the potential source of such oversized responses beyond the intended domain. ### Attack Path 1. An accepted URL directly returns, or redirects to, an unusually large response. 2. The script calls `resp.read()` and attempts to buffer the complete response. 3. Decoding and HTML extraction cause additional memory consumption. 4. The normalized result is written to the cache, consuming disk space. 5. The process may terminate due to memory exhaustion, or the host may experience degraded availability or exhausted storage. ### Impact Assessment Successful exploitation can cause denial of service against the script process and potentially affect other workloads on the same host through memory or disk exhaustion. The issue does not grant code execution, elevated privileges, or access to local secrets.
Remediation
## Remediation Suggestions - Define a conservative maximum response size appropriate for documentation pages. - Reject responses whose declared `Content-Length` exceeds that limit. - Read the body incrementally in bounded chunks and stop once the cumulative limit is exceeded; do not rely solely on `Content-Length`. - Validate the response media type and accept only expected textual or HTML content. - Apply separate limits to extracted text and final cache-file size. - Remove partially written output on failure and report a clear error. - Combine these controls with strict redirect validation so unapproved destinations cannot supply oversized content.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a user-facing Kubernetes expertise workflow for handling Kubernetes questions, troubleshooting, command planning, and cluster/resource behavior. The supplied code does not perform analysis of Kubernetes requests, command planning, troubleshooting, or cluster operations. Instead, its primary function is to download a Kubernetes documentation page from kubernetes.io/docs, strip HTML to text, and save the result locally as cached markdown. While this supports a documentation-oriented system, the actual code chunk is a content acquisition/cache script, which is a materially different primary purpose and introduces undeclared capabilities: outbound network fetching and filesystem writes. Therefore the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a skill used for Kubernetes-focused question answering and operational guidance. The supplied code does not inspect Kubernetes state, answer questions, retrieve docs, troubleshoot clusters, or interact with Kubernetes APIs or `kubectl`. Instead, it creates a local note/documentation workspace on disk with predefined folders and markdown seed files. That is a materially different primary purpose: filesystem scaffolding/setup rather than Kubernetes-specific workflow execution. While the created file names reference Kubernetes, the actual behavior is just local initialization, which is undeclared in the description.

Credential Access

High
Category
Privilege Escalation
Content
## Secrets / Sensitive Data

- Do not store plaintext credentials, API keys, session tokens, private URLs, recovery codes, kubeconfigs, client certificates, bearer tokens, or other secrets in the encyclopedia notes/inventory tree.
- If a note needs to mention access details, keep it high-level and redact or omit secret material.
- Treat these workspace notes as operational memory, not as a secrets vault.
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill clearly instructs the agent to fetch remote Kubernetes documentation and write cached copies and notes to the local workspace, but it declares no explicit tool scope or permissions. That creates an authorization and governance gap: a caller may invoke a skill that performs network access and filesystem writes beyond what its manifest formally discloses.

Static analysis

No suspicious patterns detected.