Back to skill

Security audit

Helm Chart Linter

Security checks for vulnerabilities and agentic risk

Overview

This is a read-only Helm chart linter with no hidden persistence or network behavior, but its security checks are heuristic and should not be your only review.

Install only if you want a lightweight local Helm chart checker. Treat its security output as advisory, especially for resource limits and non-root execution, and avoid publishing reports that may include snippets from values.yaml if those files contain real secrets.

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/helm_chart_linter.py:391
Finding
Resource-limit validation can be bypassed by an empty or requests-only resources block## Vulnerability Details **File Location**: `scripts/helm_chart_linter.py:391-397` **Vulnerability Type**: Incomplete security validation leading to false-negative results **Risk Level**: Medium ### Vulnerable Code ```python def check_resource_limits(chart_dir: str) -> list: issues = [] for tpl_path in find_template_files(chart_dir): text = read_file(tpl_path) # Only check files that look like Deployment/StatefulSet/DaemonSet if not re.search(r'kind\s*:\s*(Deployment|StatefulSet|DaemonSet|Job|CronJob)', text): continue if 'limits:' not in text and 'resources:' not in text: issues.append(Issue('SEC004', 'warning', f'No resource limits defined in {os.path.basename(tpl_path)}', tpl_path)) return issues ``` ### Technical Analysis The SEC004 rule is documented as verifying that resource limits are defined. Its implementation suppresses the warning whenever either `limits:` or `resources:` appears anywhere in the template. A Kubernetes workload can contain a `resources:` block with only `requests`, an empty resources block, or an unrelated textual occurrence without defining any container resource limits. All such cases satisfy the current substring test and incorrectly pass SEC004. The implementation also searches the complete template as unstructured text, so limits belonging to one container can conceal missing limits on other containers or init containers. ### Attack Path 1. A chart author creates a Deployment, StatefulSet, DaemonSet, Job, or CronJob template. 2. The workload contains a requests-only block such as: ```yaml resources: requests: cpu: 100m memory: 128Mi ``` 3. No `resources.limits` values are configured. 4. The chart is checked with the `security`, `lint`, or `validate` command. 5. Because the template contains the substring `resources:`, the conditional expression eva ...[truncated 720 chars]
Remediation
## Remediation Suggestions - Render Helm templates and parse the resulting Kubernetes YAML structurally rather than relying on document-wide substring searches. - For every workload, inspect every regular container and init container independently. - Require a non-empty `resources.limits` mapping with the desired CPU and memory keys. - Do not treat the presence of `resources:` or limits assigned to another container as sufficient. - Report the workload, container name, file, and document location for each missing limit. - Add regression tests for requests-only resources, empty resources, limits on only one of multiple containers, limits in comments, and templated resources.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/helm_chart_linter.py:400
Finding
Root-execution validation misses absent controls and accepts runAsUser UID 0## Vulnerability Details **File Location**: `scripts/helm_chart_linter.py:400-413` **Vulnerability Type**: Incomplete container identity validation leading to false-negative results **Risk Level**: Medium ### Vulnerable Code ```python def check_run_as_root(chart_dir: str) -> list: issues = [] for tpl_path in find_template_files(chart_dir): text = read_file(tpl_path) if not re.search(r'kind\s*:\s*(Deployment|StatefulSet|DaemonSet|Job)', text): continue has_security_context = 'securityContext' in text has_run_as_non_root = re.search(r'runAsNonRoot\s*:\s*true', text) has_run_as_user = re.search(r'runAsUser\s*:\s*\d+', text) if has_security_context and not has_run_as_non_root and not has_run_as_user: issues.append(Issue('SEC005', 'warning', f'securityContext present but runAsNonRoot/runAsUser not set in {os.path.basename(tpl_path)}', tpl_path)) return issues ``` ### Technical Analysis SEC005 is intended to detect workloads that may run as root, but the rule reports an issue only when a `securityContext` string is present and neither of the other strings is found. Consequently, a workload with no security context receives no warning even though its effective user depends on the container image and may be root. The expression used for `runAsUser` accepts every non-negative numeric UID, including `runAsUser: 0`, which explicitly requests root. A match anywhere in the template also suppresses the finding for the entire workload, so a compliant pod-level or container-level setting may conceal unsafe settings in another container. Text in comments or unrelated YAML structures can likewise affect the result. ### Attack Path 1. A chart author supplies a supported workload template. 2. The author either omits `securityContext` entirely or configures: ```yaml securityContext: runAsUser: ...[truncated 1216 chars]
Remediation
## Remediation Suggestions - Treat the absence of an explicit non-root policy as a reportable condition for each applicable container. - Require `runAsNonRoot: true` at an effective pod or container level. - Explicitly reject `runAsUser: 0`; if a numeric UID is used as supporting evidence, require it to be greater than zero. - Evaluate pod-level defaults and container-level overrides according to Kubernetes inheritance behavior. - Inspect regular containers and init containers separately so one compliant configuration cannot conceal another unsafe container. - Render Helm templates and parse each Kubernetes object structurally instead of using whole-file regular expressions. - Add regression tests for missing security contexts, UID 0, quoted UID 0, mixed safe and unsafe containers, comments containing policy strings, and container-level overrides.
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Privileged Kubernetes Workload

High
Category
Tool Misuse
Content
### Security (6 rules)
7. `SEC001` — No hardcoded secrets in values.yaml (passwords, tokens, keys)
8. `SEC002` — No privileged containers (securityContext.privileged: true)
9. `SEC003` — No hostNetwork, hostPID, or hostIPC enabled
10. `SEC004` — Resource limits defined in templates
11. `SEC005` — No runAsRoot without explicit runAsNonRoot
Confidence
70% confidence
Finding
Code deploys a privileged Kubernetes workload (privileged container, hostPath mount, or host namespaces). This grants root on the node and is a node/cluster takeover vector.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares executable/file-reading capability context but does not specify any tool scope such as permissions or allowed-tools. In agent environments, missing scope boundaries can cause the skill to be invoked with broader file access than intended, increasing the risk of unauthorized reading of workspace files or sensitive chart-related data.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad enough that the skill may activate for loosely related requests such as general validation or auditing tasks. Over-broad invocation increases the chance of unintended execution and unnecessary file access, especially when combined with unspecified tool scope.

Missing User Warnings

Low
Confidence
77% confidence
Finding
This code traverses the provided chart directory and reads multiple files under it via helper functions such as os.walk and open(), which is a form of filesystem access. Although the tool's purpose is linting a chart directory, there is no user-facing warning, print, or comment near execution indicating that it will recursively inspect files under the target path.

Static analysis

No suspicious patterns detected.