Back to skill

Security audit

huawei-cloud-skill-tester

Security checks across malware telemetry and agentic risk

Overview

This cloud testing skill has a coherent purpose, but it can run generated commands and cloud write operations with Huawei credentials without the user confirmations it promises.

Review carefully before installing. Use only disposable, least-privilege Huawei Cloud test credentials in an isolated environment, avoid production accounts, inspect generated phase-3 test cases before Phase 4, and do not run --all-installed or --fresh unless you are comfortable with local skill installs, phase files, reports, and cloud resources being changed or removed.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (30)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill describes and enables powerful capabilities—environment-variable access, file read/write, and shell execution—while declaring no explicit permissions or user-facing safety boundaries. This creates a transparency and consent gap: users may invoke a skill that can inspect credentials, modify local files, and run commands without having been clearly warned about that authority.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The file header claims the phase is read-only and that write operations require per-action user confirmation, but the implementation later auto-confirms write cases and executes them with live AK/SK credentials. This mismatch is dangerous because operators may trust the documented safety model while the script actually performs authenticated state-changing actions in a non-interactive pipeline.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The script claims a user-confirmed full-flow test, but no actual confirmation is collected before potentially impactful execution, and the generated metadata inconsistently marks scenarios as confirmed. This creates a dangerous trust boundary failure: downstream users or automation may believe destructive actions were explicitly approved when they were not.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
In the multi-skill path, the script fabricates a successful-looking scenario, state consistency, and cleanup report without actually executing the commands or validating resource state. This can mislead operators into believing end-to-end integration and cleanup succeeded, causing unsafe deployments, orphaned resources, or missed failures.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger set includes broad terms such as 'verification', 'e2e', '跑测试', and similar generic phrases that are likely to collide with normal user requests. Overbroad triggers can cause the skill to activate unexpectedly in unrelated contexts, increasing the chance of accidental execution of shell-driven workflows or credential prompts.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly instructs the agent to prompt for Huawei Cloud AK/SK credentials if missing, but it does not pair that behavior with a prominent sensitivity warning, secure-entry guidance, or least-retention handling. Prompting users to disclose cloud credentials in a conversational flow materially increases the risk of secret exposure, logging, or misuse.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The guide instructs users to execute a remote installer directly with `curl ... | bash`, which prevents inspection of the downloaded script and gives whatever is served at that URL immediate code execution on the user's machine. In a testing framework context this is more dangerous because users may run setup steps quickly in privileged CI, developer, or cloud-admin environments where compromise could expose credentials and infrastructure access.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The credential setup example places access keys and secret keys directly on the command line, which can leak into shell history, process listings, terminal logs, CI logs, and shared screenshots. In a Huawei Cloud skill testing framework, these are high-value cloud credentials, so accidental exposure could let an attacker access or modify cloud resources used for testing or broader tenant infrastructure.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documented `--fresh` behavior performs unconditional deletion of `phase-*.json` state files before restarting from Phase 0. In a testing framework that relies on resumable phase outputs and consolidated reporting, this can destroy audit/recovery artifacts and cause accidental data loss if invoked unintentionally or by automation, especially because the rule text shows no confirmation, backup, or scoped safety checks.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script reads the secret key with plain read -r, which echoes the credential to the terminal and can expose it to shoulder-surfing, terminal recording, shared-session logs, or operator screenshots. Because this skill is specifically for Huawei Cloud testing and handles real AK/SK credentials, unmasked input materially increases the chance of credential disclosure.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script performs a destructive uninstall for local skills via `rm -rf "$target_dir"` as part of an automated test flow, with no explicit user confirmation, dry-run mode, or prominent warning at execution time. In this skill’s context, the behavior is more dangerous because the framework is designed to run end-to-end tests automatically across skills, so invoking it can unexpectedly remove installed skill directories from `~/.hermes/skills` and disrupt a user environment.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The remote install/uninstall path uses `hermes skills install ... --yes` and `hermes skills uninstall ... --yes`, which suppresses interactive safety checks and makes state-changing operations happen silently. In a testing skill that accepts remote skill URLs, this increases risk because a user can trigger package installation/removal without meaningful disclosure, potentially trusting remote content or altering local configuration unexpectedly.

Missing User Warnings

High
Confidence
99% confidence
Finding
When a test case is marked as a write, the code prints a warning but then sets user_confirmed to true and proceeds, explicitly stating that non-interactive mode will directly execute write operations with AK/SK credentials. That removes the only intended safety barrier before creating, deleting, or modifying cloud resources and enables unintended or malicious destructive actions embedded in test cases.

Missing User Warnings

High
Confidence
99% confidence
Finding
CLI command text is taken from test case data and executed via bash -c with the full inherited environment, including cloud credentials. Because the test cases come from an earlier phase and are treated as executable content, a crafted case can run arbitrary shell commands, exfiltrate secrets, or perform unauthorized cloud and local-system actions.

Missing User Warnings

High
Confidence
99% confidence
Finding
For SDK cases, the script writes Python code from test case data to a temporary file and executes it directly. This is arbitrary code execution under the tester's privileges with access to inherited environment variables and cloud credentials, so a malicious test case can execute local commands, read files, exfiltrate secrets, or manipulate cloud resources.

Missing User Warnings

High
Confidence
97% confidence
Finding
The fallback SDK path dynamically constructs authenticated clients and invokes methods such as create_servers and delete_servers without any confirmation gate. Although method names are limited by a mapping, the mapped set already includes state-changing APIs, so the code can create or delete resources automatically using harvested credentials.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script executes Python snippets and shell commands sourced from phase-1 data, including bash -c and generated Python files, with inherited environment variables and cloud credentials. If phase-1 data or skill metadata is attacker-controlled, this becomes arbitrary code execution that can run destructive cloud actions or exfiltrate secrets such as AK/SK.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
snippet_lines.append('from huaweicloudsdk%s.%s import %s, %s' % (svc, sdk_ver, client_cls, request_class))
    snippet_lines.append('')
    snippet_lines.append('ak, sk = "", ""')
    snippet_lines.append('for k, v in os.environ.items():')
    snippet_lines.append('    u = k.upper()')
    snippet_lines.append("    if not (u.startswith('HUAWEI') or u.startswith('HW') or u.startswith('HWC')): continue")
    snippet_lines.append("    if 'ACCESS_KEY' in u or u.endswith('_AK') or u == 'AK': ak = v or ak")
Confidence
96% confidence
Finding
The generated Python SDK snippets enumerate all environment variables and heuristically extract credentials from any variable whose name matches AK/SK patterns. In this skill context, the script parses potentially adversarial SKILL.md content and auto-generates executable commands, so broad environment harvesting increases the chance that unintended credentials are consumed by untrusted generated test code and used against real Huawei Cloud resources.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
client_class = getattr(mod, client_cls_name)
                        from huaweicloudsdkcore.auth.credentials import BasicCredentials, GlobalCredentials
                        ak, sk = '', ''
                        for k, v in os.environ.items():
                            u = k.upper()
                            if not (u.startswith('HUAWEI') or u.startswith('HW') or u.startswith('HWC')): continue
                            if 'ACCESS_KEY' in u or u.endswith('_AK') or u == 'AK': ak = v or ak
Confidence
88% confidence
Finding
This loop harvests AK/SK-style credentials from any environment variable whose name matches broad Huawei/HW/HWC prefixes and passes them into authenticated SDK clients. In this file's context, the harvesting itself is used for cloud access rather than direct exfiltration, but combined with the arbitrary command and code execution paths it increases blast radius by making secrets broadly available to untrusted execution paths.

Unvalidated Output Injection

High
Category
Output Handling
Content
# Remove leading/trailing pipes and whitespace that might leak from table extraction
            cmd_text = cmd_text.strip().lstrip('|').strip()
            if cmd_text and len(cmd_text) > 5:
                r = subprocess.run(
                    ['bash', '-c', cmd_text],
                    capture_output=True, text=True, timeout=int(os.environ.get('TIMEOUT_CLI', '30')),
                    env=os.environ
Confidence
99% confidence
Finding
The script executes untrusted command text through bash -c, which is classic command injection / arbitrary shell execution. In this skill's testing context, that is especially dangerous because the process inherits cloud credentials and is specifically designed to run against real environments, turning malformed or malicious test data into immediate local and cloud compromise.

Unvalidated Output Injection

High
Category
Output Handling
Content
method_name = tc.get('method_name', '')
            # If command starts with python3 -c, run as bash (it's a one-liner, not a snippet)
            if cmd_text.startswith('python3 -c ') or cmd_text.startswith('python3  -c '):
                r = subprocess.run(
                    ['bash', '-c', cmd_text],
                    capture_output=True, text=True, timeout=int(os.environ.get('TIMEOUT_CLI', '30')),
                    env=os.environ
Confidence
99% confidence
Finding
This path runs a test-supplied python3 -c one-liner via bash -c, allowing arbitrary code execution from untrusted test definitions. Because the environment is inherited, the executed payload can access credentials, local files, and network connectivity, making the testing framework an execution vector.

Unvalidated Output Injection

High
Category
Output Handling
Content
try:
                    sdk_tmp.write(cmd_text)
                    sdk_tmp.close()
                    r = subprocess.run(
                        ['python3', sdk_tmp.name],
                        capture_output=True, text=True, timeout=60,
                        env=os.environ
Confidence
99% confidence
Finding
The script persists attacker-controlled Python content to disk and executes it with python3, which is arbitrary code execution rather than simple test orchestration. In the context of a cloud skill tester, this can be used to steal AK/SK, tamper with reports, pivot into the host, or perform unauthorized cloud operations.

Unvalidated Output Injection

High
Category
Output Handling
Content
script_args = ' '.join(script_part.split()[1:]) if len(script_part.split()) > 1 else ''
                if os.path.isfile(script_path):
                    full_cmd = f'python3 {script_path} {script_args}'.strip()
                    r = subprocess.run(['bash', '-c', full_cmd], capture_output=True, text=True, timeout=60, env=os.environ)
                    output = (r.stdout[:1000] + '\n' + r.stderr[:500]).strip()
                    status = 'pass' if r.returncode == 0 else 'fail'
                else:
Confidence
96% confidence
Finding
full_cmd is assembled from parsed test case text and executed via bash -c, so script arguments can inject additional shell syntax or commands. Even if the base script path is validated, untrusted arguments remain a command injection vector and run with inherited credentials.

Unvalidated Output Injection

High
Category
Output Handling
Content
if not os.path.isfile(script_path):
                    script_path = os.path.join(skill_root, 'scripts', os.path.basename(script_part))
                if os.path.isfile(script_path):
                    r = subprocess.run(['bash', script_path, skill_root], capture_output=True, text=True, timeout=60)
                    output = (r.stdout[:1000] + '\n' + r.stderr[:500]).strip()
                    status = 'pass' if r.returncode == 0 else 'fail'
                else:
Confidence
72% confidence
Finding
This line executes a resolved script file directly with bash rather than through bash -c, so classic shell-string injection is not present at this exact call site. However, it still runs a script selected from test case data without approval, which is risky, but that broader issue is better captured by the SQP-2 findings than by this specific output-injection pattern.

Unvalidated Output Injection

High
Category
Output Handling
Content
# Unknown executor: try running command text as shell command
            cmd_text = tc.get('command', '')
            if cmd_text.strip() and len(cmd_text) > 10:
                r = subprocess.run(
                    ['bash', '-c', cmd_text],
                    capture_output=True, text=True, timeout=30,
                    env={**__import__('os').environ}
Confidence
99% confidence
Finding
The unknown-executor fallback executes arbitrary command text with bash -c, meaning any unrecognized test case can still become a shell payload. This broad fallback defeats attempts to constrain execution types and provides a universal arbitrary-command path with inherited environment access.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.