Back to skill

Security audit

Kubernetes DevOps Toolkit

Security checks for vulnerabilities and agentic risk

Overview

This Kubernetes toolkit is mostly purpose-aligned, but its Helm commands can modify the wrong cluster because they ignore the configured kubeconfig.

Review carefully before installing in any environment with production Kubernetes access. Use only with a clearly isolated kubeconfig/context, verify the active Helm context before running install, upgrade, or rollback, and prefer a patched version that passes the selected kubeconfig explicitly to every Helm command.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/kubernetes_devops_toolkit.py:406
Finding
Helm operations ignore the caller-specified kubeconfig and may target an unintended cluster<![CDATA[ ## Vulnerability Details **File Location**: `scripts/kubernetes_devops_toolkit.py:406-439` **Additional Affected Locations**: `scripts/kubernetes_devops_toolkit.py:459-477`, `scripts/kubernetes_devops_toolkit.py:495-500`, `scripts/kubernetes_devops_toolkit.py:516-527` **Vulnerability Type**: Cluster-target configuration mismatch **Risk Level**: High ### Vulnerable Code ```python def __init__(self, kubeconfig_path: Optional[str] = None): self.kubeconfig_path = kubeconfig_path or "~/.kube/config" def install(self, release_name: str, chart: str, namespace: str = "default", values: Optional[Dict[str, Any]] = None, version: Optional[str] = None) -> bool: """ Install a Helm chart. Args: release_name: Name for the release chart: Chart reference (repo/chart or path) namespace: Target namespace values: Values to override version: Chart version Returns: bool: True if installation successful """ # Implementation would use helm CLI or pyhelm import subprocess cmd = ["helm", "install", release_name, chart, "-n", namespace] if values: for key, val in values.items(): cmd.extend(["--set", f"{key}={val}"]) if version: cmd.extend(["--version", version]) try: result = subprocess.run(cmd, capture_output=True, text=True, check=True) return True except subprocess.CalledProcessError as e: print(f"Helm install failed: {e.stderr}") return False ``` The same omission is present in the `upgrade`, `rollback`, and `list_releases` command construction. ### Technical Analysis `HelmManager` accepts and stores a `kubeconfig_path`, creating the reasonable expectation that Helm operations will use that configuration. However, none of the generated Helm commands includes `--kubeconfig`, and the subprocess environment is not configured with an equivalent `KUBECONFIG` value. C ...[truncated 1948 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pass the selected kubeconfig explicitly to every Helm invocation: ```python from pathlib import Path kubeconfig = str(Path(self.kubeconfig_path).expanduser().resolve()) cmd = [ "helm", "install", release_name, chart, "--namespace", namespace, "--kubeconfig", kubeconfig, ] ``` 2. Apply the same correction to `install`, `upgrade`, `rollback`, and `list_releases`. 3. Validate that the kubeconfig exists, is a regular file, and has appropriately restrictive permissions before invoking Helm. 4. Consider accepting an explicit context and passing `--kube-context` to prevent reliance on the kubeconfig's current context. 5. Before mutating a cluster, retrieve and display or verify the selected context and cluster endpoint. 6. Require explicit confirmation for high-impact operations when the selected context appears to be production. 7. Add mocked subprocess tests asserting that every generated Helm command includes the expected `--kubeconfig` and, when configured, `--kube-context` arguments. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Open-ended dependency constraints make installations non-reproducible<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-26` **Vulnerability Type**: Unconstrained dependency resolution and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```text # Kubernetes DevOps Toolkit - Dependencies # Kubernetes Client kubernetes>=28.1.0 # YAML Processing PyYAML>=6.0.1 # CLI Interface click>=8.1.0 rich>=13.5.0 # HTTP Client requests>=2.31.0 # Async Support aiohttp>=3.8.0 # Testing pytest>=7.4.0 pytest-asyncio>=0.21.0 pytest-cov>=4.1.0 # Utilities tabulate>=0.9.0 python-dateutil>=2.8.0 ``` ### Technical Analysis Every dependency uses a lower-bound-only constraint. An installation can therefore resolve to arbitrary future versions that were not reviewed or tested with this project. No lock file or package hashes are provided to authenticate the exact artifacts being installed. This does not prove that any currently listed package is malicious. The weakness is that the project cannot reproduce or enforce a reviewed dependency set. A future compromised release, incompatible major version, or compromised artifact accepted by the resolver could enter the installation without any project change. Several declared packages are also not imported by the current implementation. Keeping unnecessary dependencies increases the number of packages and transitive dependencies that must be trusted. ### Attack Path 1. A user follows the documented installation command: `pip install -r requirements.txt`. 2. The package resolver queries the configured Python package index. 3. It selects the newest versions satisfying the open-ended `>=` constraints. 4. A future compromised or unexpectedly incompatible direct or transitive release is selected. 5. Package installation hooks or imported package code execute with the user's operating-system privileges. 6. When the toolkit runs, compromised dependency code may also execute in a process that can read kubeconfig credentials and communicate with Kubernetes APIs. Thi ...[truncated 894 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate and commit a lock file containing exact, reviewed direct and transitive versions. 2. Use exact pins for deployable environments rather than lower-bound-only constraints. 3. Record cryptographic hashes and install with hash verification, for example through `pip --require-hashes`. 4. Separate runtime requirements from development and testing requirements. 5. Remove unused dependencies unless planned functionality requires them. 6. Use automated vulnerability and provenance scanning during continuous integration. 7. Review dependency updates through controlled pull requests and test them before release. 8. Configure installation to use a trusted package index and avoid unreviewed additional indexes. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (53)

Credential Access

High
Category
Privilege Escalation
Content
print("\n1. Initialize K8s Manager")
    print("-" * 40)
    manager = K8sManager(kubeconfig_path="~/.kube/config")
    print(f"   Kubeconfig: {manager.kubeconfig_path}")
    
    # List available contexts
    print("\n2. List Available Contexts")
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
80% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
def test_init_default(self):
        """Test default initialization"""
        manager = K8sManager()
        assert manager.kubeconfig_path == "~/.kube/config"
        assert manager.context is None
        assert not manager.is_connected()
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.