Back to skill

Security audit

huawei-cloud-cce-metric-analyzer

Security checks across malware telemetry and agentic risk

Overview

The skill is mostly read-only and purpose-related, but it uses broad cloud and Kubernetes access, including TLS Secret reads and generated kubeconfig material, enough that users should review it before installing.

Install only with a least-privilege Huawei IAM user and Kubernetes RBAC limited to the documented read-only resources. Avoid production or broad cluster-admin credentials, prefer short-lived credentials, unset environment secrets after use, and consider disabling certificate checks with check_certificates=false unless ingress TLS expiration data is specifically needed.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares itself as read-only and documents shell, environment, and network-backed execution paths, but it does not expose an explicit permissions model. That creates a governance gap: a caller or platform may treat the skill as lower risk than it really is, even though it can access credentials from the environment and make authenticated cloud and Kubernetes queries.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented purpose understates the actual behavior: beyond metric reads, the skill can enumerate clusters and nodes, query GPU/xGPU telemetry, read Kubernetes pods/services/ingresses/secrets, generate kubeconfig material, and correlate external resources through cluster API access. This mismatch is dangerous because operators may authorize the skill for narrow observability use while it exercises broader discovery and sensitive-read capabilities than expected.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This module exposes a function that retrieves full Kubernetes Secret objects, which can include base64-encoded credentials, tokens, certificates, and other highly sensitive material. That capability is not justified by the declared metric-analysis purpose, so it materially expands privilege and data-exfiltration risk beyond user expectations.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest frames this as a metric-analysis skill, but the code performs broad Kubernetes enumeration of services, pods, ingresses, and secrets via kubectl. This scope mismatch is dangerous because it gives an apparently low-risk monitoring skill unexpected cluster-discovery and sensitive-data-access capabilities.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The guide instructs users to place Huawei Cloud access keys, project IDs, and temporary security tokens into environment variables without any guidance on secure handling, scoping, rotation, or cleanup. Environment variables are commonly exposed through shell history, process inspection, debug dumps, CI logs, and inherited subprocesses, so documenting this pattern without warnings increases the chance of credential leakage.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation tells users to place long-lived cloud credentials and IAM tokens directly into shell environment variables without any warning about secret handling, shell history, process exposure, or use of safer credential mechanisms. In a cloud operations skill, this is risky because users may run commands in shared terminals, CI logs, shell profiles, or support sessions, leading to credential leakage and unauthorized access to Huawei Cloud resources.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Sensitive secret retrieval is implemented with no user-facing warning, confirmation, or authorization barrier. In an agent setting, that makes it much easier for a prompt or workflow to exfiltrate cluster secrets silently under the guise of normal analysis activity.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
access_key = ak or os.environ.get("HUAWEI_AK") or os.environ.get("HUAWEICLOUD_SDK_AK") or os.environ.get("HW_ACCESS_KEY")
    secret_key = sk or os.environ.get("HUAWEI_SK") or os.environ.get("HUAWEICLOUD_SDK_SK") or os.environ.get("HW_SECRET_KEY")
    proj_id = project_id or os.environ.get("HUAWEI_PROJECT_ID") or os.environ.get("HUAWEICLOUD_SDK_PROJECT_ID") or os.environ.get("HW_PROJECT_ID")
    env = os.environ.copy()
    env["CCE_CLUSTER_ID"] = cluster_id
    env["CCE_REGION"] = region
    env["HW_REGION"] = region
Confidence
88% confidence
Finding
Copying the entire parent environment into a child kubectl process can unnecessarily propagate unrelated secrets, tokens, proxies, and configuration into an external command context. In an agent environment, this increases blast radius because any kubectl plugin, exec auth helper, or misconfigured binary invoked by kubectl may inherit far more secret material than needed.

Credential Access

High
Category
Privilege Escalation
Content
It also includes CoreDNS, nginx-ingress, and autoscaler summaries. Cloud resources are scoped to the current cluster when an association can be proven: ELB is matched through LoadBalancer Service IP/EIP, NAT Gateway is filtered by the cluster VPC, and EIP is limited to associated ELB/NAT/Service IPs.

LoadBalancer Service discovery uses `kubectl` with generated kubeconfig through the cluster EIP when external access is available. If the cluster has no EIP, it uses the `kubectl cce` plugin. If neither path works, aggregation fails.

## Risk Levels
Confidence
90% confidence
Finding
The skill states it generates and uses kubeconfig to access the cluster API and may fall back to explicit AK/SK or environment credentials for signed requests. Even if intended for read-only operations, handling kubeconfig and cloud credentials increases credential exposure risk through logs, temp files, subprocess arguments, shell history, or unintended disclosure to downstream tools.

Credential Access

High
Category
Privilege Escalation
Content
return {"success": True, "cluster": result.get("data") or {}}


def _create_kubeconfig(region: str, cluster_id: str, ak: Optional[str], sk: Optional[str], project_id: Optional[str]) -> Dict[str, Any]:
    result = run_hcloud(
        "CCE",
        "CreateKubernetesClusterCert",
Confidence
92% confidence
Finding
The code requests a Kubernetes cluster certificate/kubeconfig via CreateKubernetesClusterCert, creating direct cluster access credentials. In the context of a metric-analysis skill, generating operational access material is a significant privilege expansion that can enable broad cluster reads and potentially further abuse depending on RBAC.

Credential Access

High
Category
Privilege Escalation
Content
if not _cluster_has_external_access(cluster_result.get("cluster") or {}):
        return {"success": False, "error": "cluster has no bound EIP/external endpoint"}

    kubeconfig_result = _create_kubeconfig(region, cluster_id, ak, sk, project_id)
    if not kubeconfig_result.get("success"):
        return kubeconfig_result
Confidence
90% confidence
Finding
The code invokes kubeconfig creation after confirming the cluster has an external endpoint, effectively turning cloud credentials into direct Kubernetes API access material. In this skill context, that is a risky privilege escalation path because a monitoring-oriented capability can pivot into broad cluster interrogation.

Credential Access

High
Category
Privilege Escalation
Content
if not _cluster_has_external_access(cluster_result.get("cluster") or {}):
        return {"success": False, "error": "cluster has no bound EIP/external endpoint"}

    kubeconfig_result = _create_kubeconfig(region, cluster_id, ak, sk, project_id)
    if not kubeconfig_result.get("success"):
        return kubeconfig_result
Confidence
90% confidence
Finding
The code invokes kubeconfig creation after confirming the cluster has an external endpoint, effectively turning cloud credentials into direct Kubernetes API access material. In this skill context, that is a risky privilege escalation path because a monitoring-oriented capability can pivot into broad cluster interrogation.

Credential Access

High
Category
Privilege Escalation
Content
if not kubeconfig_result.get("success"):
        return kubeconfig_result

    kubeconfig_file = None
    try:
        with tempfile.NamedTemporaryFile("w", delete=False, suffix=".json") as handle:
            json.dump(kubeconfig_result["kubeconfig"], handle)
Confidence
96% confidence
Finding
The code writes generated kubeconfig credentials to a named temporary file on disk using delete=False. Even though it later removes the file, writing cluster access credentials to disk creates a theft window, may leave recoverable traces, and can expose sensitive material to other local processes depending on platform and file-handling behavior.

Credential Access

High
Category
Privilege Escalation
Content
kubeconfig_file = None
    try:
        with tempfile.NamedTemporaryFile("w", delete=False, suffix=".json") as handle:
            json.dump(kubeconfig_result["kubeconfig"], handle)
            kubeconfig_file = handle.name
        result = _run_json_command(["kubectl", "--kubeconfig", kubeconfig_file, "get", *resource_args, "-o", "json"])
        if result.get("success"):
Confidence
95% confidence
Finding
This line serializes the kubeconfig contents to the temporary file, concretely materializing sensitive cluster credentials on disk. In an agent runtime, that can expose credentials through filesystem inspection, crash artifacts, backups, or concurrent local compromise.

Credential Access

High
Category
Privilege Escalation
Content
kubeconfig_file = None
    try:
        with tempfile.NamedTemporaryFile("w", delete=False, suffix=".json") as handle:
            json.dump(kubeconfig_result["kubeconfig"], handle)
            kubeconfig_file = handle.name
        result = _run_json_command(["kubectl", "--kubeconfig", kubeconfig_file, "get", *resource_args, "-o", "json"])
        if result.get("success"):
Confidence
95% confidence
Finding
This line serializes the kubeconfig contents to the temporary file, concretely materializing sensitive cluster credentials on disk. In an agent runtime, that can expose credentials through filesystem inspection, crash artifacts, backups, or concurrent local compromise.

Credential Access

High
Category
Privilege Escalation
Content
try:
        with tempfile.NamedTemporaryFile("w", delete=False, suffix=".json") as handle:
            json.dump(kubeconfig_result["kubeconfig"], handle)
            kubeconfig_file = handle.name
        result = _run_json_command(["kubectl", "--kubeconfig", kubeconfig_file, "get", *resource_args, "-o", "json"])
        if result.get("success"):
            result["access_method"] = "kubectl_kubeconfig_external"
Confidence
93% confidence
Finding
Passing the kubeconfig file to kubectl operationalizes the generated cluster credentials for arbitrary resource retrieval. This turns a metrics skill into a direct cluster-access client, substantially increasing abuse potential if the skill is invoked by an untrusted prompt or loosely governed workflow.

Credential Access

High
Category
Privilege Escalation
Content
profile_ak, profile_sk, profile_project = get_credentials(ak, sk, project_id)
    kubeconfig_result = _kubectl_get_with_kubeconfig(region, cluster_id, resource_args, profile_ak, profile_sk, profile_project)
    if kubeconfig_result.get("success"):
        return kubeconfig_result

    plugin_result = _kubectl_get_with_cce_plugin(region, cluster_id, resource_args, ak, sk, project_id, security_token)
    if plugin_result.get("success"):
Confidence
89% confidence
Finding
Falling back to the kubectl cce plugin preserves direct cluster-access behavior even when kubeconfig-based access fails. This broadens the number of successful credentialed paths into the cluster, making unintended data access more likely in a skill that should be confined to metrics analysis.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.