Back to skill

Security audit

k1-kzcloud-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill’s CXO lookup purpose is coherent, but its login helper handles passwords and tokens in unsafe ways that could expose accounts or allow local command execution.

Review carefully before installing. Use only if you trust the K1 endpoint and accept that the current login script may expose your password or bearer token through command arguments, logs, persistent environment storage, or network interception. The publisher should enable TLS verification, stop printing tokens, avoid persistent environment-variable token storage, prompt for passwords securely, and remove the PowerShell token interpolation before broad use.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login.py:16
Finding

TLS Certificate Verification Is Disabled for Authentication Requests

Content
View full analysis

Vulnerability Details

File Location: scripts/login.py, lines 4-6, 16-27, and 100-104
Vulnerability Type: Improper certificate validation
Risk Level: Critical

Vulnerable Code

python
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
requests.packages.urllib3.disable_warnings()
python
def __init__(self, base_url="http://your-backend-url"):
    self.base_url = base_url
    self.session = requests.Session()
    self.session.verify = False

def get_public_key(self, account):
    """Get RSA public key"""
    url = f"{self.base_url}/api/v1/SysUser/GenerateEncryptKey"
    params = {"userName": account}

    response = self.session.get(url, params=params, verify=False)
    response.raise_for_status()
python
print(f"Logging in with account: {account}")
response = self.session.post(url, json=login_data, verify=False)
response.raise_for_status()

The configured endpoint is also a bare IP address:

json
{
  "baseUrl": "https://36.139.200.220:8081"
}

Technical Analysis

The client disables TLS certificate verification at both the session and individual-request levels. It also suppresses the warnings that would normally reveal this unsafe behavior. Consequently, HTTPS provides encryption without reliable server authentication.

This is particularly dangerous in the login flow because the client first downloads an RSA public key from the unverified endpoint and then encrypts the user's password with that key. RSA encryption does not protect the password if an attacker can replace the public key. A man-in-the-middle attacker can provide an attacker-controlled certificate and public key, allowing the attacker to decrypt the submitted password.

The same attacker can modify the authentication response, including the returned access token. This compounds the command-injection risk described separately.

Base64 encoding o ...[truncated 1449 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove self.session.verify = False and every verify=False argument.
  2. Remove the suppression of InsecureRequestWarning.
  3. Configure the service with a DNS hostname covered by a valid certificate from a trusted certificate authority.
  4. If a private certificate authority is necessary, provide its CA bundle explicitly:
    python
    session.verify = "/secure/path/to/private-ca.pem"
    
  5. Do not implement a fallback that retries with verification disabled.
  6. Consider certificate or public-key pinning if the deployment model requires additional protection, while maintaining a secure key-rotation procedure.
  7. Validate the schema and expected cryptographic properties of the public-key response before using it.
  8. Add automated tests confirming that invalid, expired, mismatched, and untrusted certificates cause authentication to fail closed.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login.py:118
Finding

Plaintext Password Is Supplied Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: skill.md, lines 54-56; scripts/login.py, lines 118-121
Vulnerability Type: Plaintext credential exposure through process arguments
Risk Level: High

Vulnerable Code

The documented login command places the password directly on the command line:

text
python scripts/login.py --account {user account} --password {user password} --tenant_id {tenant id}

The script requires the corresponding command-line option:

python
parser = argparse.ArgumentParser(description='User login script')
parser.add_argument('--account', '-a', type=str, required=True, help='Username or email')
parser.add_argument('--password', '-p', type=str, required=True, help='Password')
parser.add_argument('--tenant_id', '-t', type=str, required=True, default=None, help='Tenant ID')

Technical Analysis

Command-line arguments are not an appropriate channel for plaintext passwords. Depending on the operating system and execution environment, arguments may be exposed through process inspection, execution telemetry, shell history, terminal transcripts, Agent logs, debugging tools, or job-management systems.

The later RSA encryption of the password does not mitigate this local disclosure because the plaintext already exists in command-line metadata before encryption occurs. This behavior also conflicts with the Skill's claim that credentials should be forgotten immediately after login.

Attack Path

  1. The user follows the command documented in skill.md.
  2. The plaintext password is included in the process argument vector.
  3. The shell may record the complete command in history, or local monitoring software may record process creation details.
  4. A local user or process with sufficient process-observation, log-reading, or history-file access retrieves the password.
  5. The recovered password is reused against the configured service or any other service where the user reused ...[truncated 534 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the --password and -p command-line options.
  2. Prompt interactively using getpass.getpass():
    python
    from getpass import getpass
    
    password = getpass("Password: ")
    
  3. For noninteractive operation, retrieve the password from a protected operating-system credential manager or narrowly scoped secret provider.
  4. Avoid placing passwords in ordinary environment variables because those may also be exposed through diagnostics or child processes.
  5. Update skill.md so the documented command never contains a plaintext password.
  6. Minimize the lifetime of password variables and do not log the login request body.
  7. Review shell histories and execution logs generated by previous use and rotate any credentials that may have been recorded.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login.py:142
Finding

Bearer Token Is Printed in Plaintext and Persisted in a User Environment Variable

Content
View full analysis

Vulnerability Details

File Location: scripts/login.py, lines 142-157
Vulnerability Type: Sensitive token disclosure and excessive secret persistence
Risk Level: High

Vulnerable Code

python
if result.get("success") and result.get("result", {}).get("code") == 0:
    user_info = result.get("result", {}).get("data", {})
    token = user_info.get('accessToken')
    if token:
        print(f"\nLogin successful!")
        print(f"token: {token}")
        # Save token to environment variable
        import os, subprocess
        subprocess.run(
            ['powershell', '-Command',
             f"[Environment]::SetEnvironmentVariable('K1_KZClOUD_TOKEN', '{token}', 'User')"],
            capture_output=True
        )
        os.environ['K1_KZClOUD_TOKEN'] = token
        print(f"Token has been saved to user environment variable K1_KZClOUD_TOKEN")

Technical Analysis

The script writes the bearer token to standard output. This can disclose it through terminal recordings, Agent transcripts, redirected output, CI logs, debugging logs, or any other output-capture mechanism.

It also stores the token as a persistent user-level environment variable through PowerShell. This extends the token's exposure and lifetime beyond the login process. Future processes belonging to the user may inherit or retrieve the value, and the token remains available until explicitly replaced or removed.

Process-scoped storage is sufficient for a single execution but does not automatically make the token available to the parent Agent process because a child process cannot modify its parent's environment. The current persistent workaround exceeds minimum privilege and does not provide secure secret storage.

Attack Path

  1. Authentication succeeds and the API returns an access token.
  2. The script prints the complete token to standard output.
  3. An Agent transcript, terminal recorder, redirected output fi ...[truncated 953 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove print(f"token: {token}") and never include bearer tokens in user-facing messages, logs, exceptions, or transcripts.
  2. Prefer process-scoped token handling and pass the token directly to the API client without exposing it through output.
  3. If cross-process storage is required, use an operating-system credential vault rather than a persistent environment variable.
  4. Require explicit user consent before any persistent credential storage.
  5. Define token expiration, logout, revocation, deletion, and account-switching behavior.
  6. Ensure switching accounts securely replaces and removes the prior token.
  7. Restrict token scope and lifetime on the server to the minimum required API operations.
  8. Rotate tokens that may already have appeared in logs or transcripts.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login.py:149
Finding

Server-Controlled Access Token Is Interpolated into PowerShell Source Code

Content
View full analysis

Vulnerability Details

File Location: scripts/login.py, lines 149-154
Vulnerability Type: PowerShell command injection
Risk Level: Critical

Vulnerable Code

python
import os, subprocess
subprocess.run(
    ['powershell', '-Command',
     f"[Environment]::SetEnvironmentVariable('K1_KZClOUD_TOKEN', '{token}', 'User')"],
    capture_output=True
)
os.environ['K1_KZClOUD_TOKEN'] = token

Technical Analysis

Although subprocess.run receives an argument list rather than a shell command string, the script explicitly launches powershell -Command. PowerShell therefore interprets the final argument as source code.

The server-provided token is inserted inside a single-quoted PowerShell string without escaping or strict format validation. A token containing a single quote followed by PowerShell syntax can terminate the intended string and inject additional commands.

This is directly exploitable if the API server is compromised. It can also be combined with the disabled TLS verification: a network attacker can forge a successful authentication response whose accessToken field contains PowerShell code.

Attack Path

  1. An attacker compromises the authentication endpoint or intercepts the connection using the disabled TLS verification.
  2. The attacker returns a syntactically valid successful JSON response with result.code set to 0.
  3. The response's accessToken contains a single quote and attacker-selected PowerShell commands.
  4. The script assigns that value to token without validation.
  5. The f-string inserts the value into the argument supplied to powershell -Command.
  6. PowerShell parses the attacker's characters as executable source code rather than token data.
  7. The injected commands execute with the operating-system privileges of the user running the Skill.

Impact Assessment

Successful exploitation permits arbitrary command execution as the current user. T ...[truncated 435 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the PowerShell subprocess and do not construct executable source code using the token.
  2. Store persistent secrets through a native credential-manager API that accepts the token strictly as data.
  3. If a subprocess is unavoidable, pass sensitive values through a non-code data channel, such as a protected standard-input stream, and use a fixed script that never evaluates the value.
  4. Apply strict allowlist validation to the expected token format and reject unexpected quotes, separators, whitespace, or control characters. Validation should be defense in depth, not the primary fix.
  5. Restore TLS certificate verification so an unauthenticated network party cannot control the server response.
  6. Validate the authentication response schema, types, token length, and token format before processing it.
  7. Add regression tests using tokens containing quotes, semicolons, newlines, subexpressions, and other PowerShell metacharacters to confirm they cannot result in code execution.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

TLS certificate verification is explicitly disabled for a login workflow that fetches a public key and submits encrypted credentials. An attacker performing a man-in-the-middle attack could substitute their own key, decrypt the password, intercept tokens, and fully compromise authentication despite the client-side RSA encryption.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The client initializes its session with certificate verification disabled by default, making insecure transport the standard behavior for all subsequent requests. In a login helper, this is particularly dangerous because it undermines confidentiality and server authenticity for credential and token exchange.

Content

Scanner excerpt · scripts/login.py (reported line 19)May include surrounding context.

python
def __init__(self, base_url="http://your-backend-url"):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.verify = False

    def get_public_key(self, account):
        """获取RSA公钥"""

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The public-key retrieval request disables TLS verification, allowing an active network attacker to tamper with the key returned by the server. Because that key is then used to encrypt the password, key substitution enables credential compromise.

Content

Scanner excerpt · scripts/login.py (reported line 26)May include surrounding context.

python
url = f"{self.base_url}/api/v1/SysUser/GenerateEncryptKey"
        params = {"userName": account}

        response = self.session.get(url, params=params, verify=False)
        response.raise_for_status()

        result = response.json()

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

The authentication POST request disables TLS verification while transmitting login material and receiving an access token. This permits interception or modification of the authentication exchange, potentially leading to account compromise and token theft.

Content

Scanner excerpt · scripts/login.py (reported line 106)May include surrounding context.

python
}

        print(f"正在登录,账号: {account}")
        response = self.session.post(url, json=login_data, verify=False)
        response.raise_for_status()

        result = response.json()

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script prints the token and then persists it to the user's Windows environment via PowerShell, which increases exposure of a bearer credential beyond the current process. Environment variables are accessible to other local processes in some contexts and are an inappropriate long-term storage location for authentication tokens.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script silently persists the authentication token to a user environment variable via PowerShell without warning or confirmation, expanding the attack surface for credential theft. In a skill context, silently storing reusable tokens is especially risky because it affects the host environment outside the immediate script execution.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/login.py (reported line 154)May include surrounding context.

python
print(f"token: {token}")
                # 保存 token 到环境变量
                import os, subprocess
                subprocess.run(
                    ['powershell', '-Command',
                     f"[Environment]::SetEnvironmentVariable('K1_KZClOUD_TOKEN', '{token}', 'User')"],
                    capture_output=True

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill requires storing a bearer token in the persistent process environment and instructs account switching by overwriting the same variable, but it does not require user confirmation, define token lifetime, or describe how the environment is scoped and cleared. Environment variables are commonly exposed to subprocesses, logs, crash reports, or other skills running in the same agent context, so this can lead to unintended credential persistence and token leakage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill asks the user to provide account credentials for a login flow that invokes an external script and remote service, but it does not present any privacy or security warning before collecting those credentials. This creates a risk that users disclose sensitive passwords to an agent-mediated workflow without understanding where the data is sent, processed, or retained.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

The skill sends user-supplied account identifiers to an external API to enumerate tenant/account-set information before login. While this is functionally related to the stated purpose, it is still an external transmission of potentially sensitive organizational identity data, and the skill does not describe consent, minimization, or transport/privacy safeguards.

Content

Scanner excerpt · skill.md (reported line 49)May include surrounding context.

baseUrl 见同目录 config.json 文件

text
curl "{baseUrl}/api/v1/SysUser/GetUserTenants?userName={userName}"

结果 json 中 result.data[] 即账套列表,每项含 id(tenantId)和 name。 用户选择账套后,取对应的 id 作为登录时的 tenant_id 参数。

Static analysis

Detected: suspicious.exposed_secret_literal, suspicious.insecure_tls_verification, suspicious.install_untrusted_source

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/login.py:71

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
scripts/login.py:19

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
config.json:2