Back to skill

Security audit

tsa-risk

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Tencent Cloud Smart Advisor utility, but it asks for durable cloud credentials and includes overbroad IAM, console-login, and cleanup behaviors that need careful review before use.

Install only if you are comfortable giving the skill Tencent Cloud API credentials and letting it create or use console-login roles. Prefer a least-privilege sub-account and short-lived credentials, avoid storing AK/SK in shell startup files, do not share generated console links, and review or remove the role-creation and cloud-cleanup scripts before running them in a production account.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (9)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tcloud_api.py:45
Finding

TLS Certificate Verification Is Disabled When certifi Is Unavailable

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tcloud_api.py:86
Finding

Generic API Client Sends Authentication Material to a Caller-Controlled Host

Content
View full analysis
dict: secret_id = secret_id or os.environ.get("TENCENTCLOUD_SECRET_ID", "") secret_key = secret_key or os.environ.get("TENCENTCLOUD_SECRET_KEY", "") token = token or os.environ.get("TENCENTCLOUD_TOKEN", "") # ... authorization = ( f"{algorithm} " f"Credential={secret_id}/{credential_scope}, " f"SignedHeaders=content-type;host;x-tc-action, " f"Signature={signature}" ) headers = { "Authorization": authorization, "Content-Type": "application/json; charset=utf-8", "Host": host, "X-TC-Action": action, "X-TC-Timestamp": str(timestamp), "X-TC-Version": version, "X-TC-Region": region, } if token: headers["X-TC-Token"] = token req = Request( f"https://{host}", data=payload_str.encode("utf-8"), headers=headers, method="POST", ) ``` ```python service = args[0] host = args[1] action = args[2] version = args[3] result = call_api(service, host, action, version, payload, region) ``` ### Technical Analysis The command-line interface accepts `service`, `host`, `action`, and `version` without an allowlist. The supplied host becomes both the HTTPS destination and the signed `Host` header. The outgoing request exposes the SecretId in the authorization credential field, includes a SecretKey-derived signature, and may include the complete temporary session token. Although the signature does not directly reveal the SecretKey, sending authenticate ...[truncated 1282 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/create_role.py:40
Finding

Created CAM Role Receives Excessive Full-Access Policies

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login_url.py:267
Finding

Credential-Bearing Console Login URLs Are Printed into Durable Agent Output

Content
View full analysis
str: login_timestamp = int(time.time()) login_nonce = random.randint(10000, 100000000) source_string = ( f"GETcloud.tencent.com/login/roleAccessCallback?" f"action=roleLogin" f"&nonce={login_nonce}" f"&secretId={tmp_secret_id}" f"×tamp={login_timestamp}" ) login_signature = base64.b64encode( hmac.new( tmp_secret_key.encode("utf-8"), source_string.encode("utf-8"), hashlib.sha256, ).digest() ).decode("utf-8") login_url = ( f"https://cloud.tencent.com/login/roleAccessCallback?" f"algorithm=sha256" f"&secretId={quote(tmp_secret_id, safe='')}" f"&token={quote(token, safe='')}" f"&nonce={login_nonce}" f"×tamp={login_timestamp}" f"&signature={quote(login_signature, safe='')}" f"&s_url={quote(target_url, safe='')}" ) return login_url ``` ```python login_url = generate_login_url( sts_result["TmpSecretId"], sts_result["TmpSecretKey"], sts_result["Token"], target_url, ) print(output_success( login_url, target_url, duration, sts_result["RequestId"] )) ``` The Skill instructions require generating a fresh link whenever architecture data is displayed and embedding that link in Markdown output. ### Technical Analysis The URL contains a temporary SecretId, STS token, timestamp, nonce, and valid HMAC signature. It functions as a bearer-like console access artifact: possession of the complete URL may be sufficient to enter the co ...[truncated 1372 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/login_url.py:302
Finding

Console Login Redirect Target Is Not Validated

Content
View full analysis
" )) sys.exit(1) target_url = sys.argv[1] ``` ```python login_url = generate_login_url( sts_result["TmpSecretId"], sts_result["TmpSecretKey"], sts_result["Token"], target_url, ) ``` ```python login_url = ( f"https://cloud.tencent.com/login/roleAccessCallback?" f"algorithm=sha256" f"&secretId={quote(tmp_secret_id, safe='')}" f"&token={quote(token, safe='')}" f"&nonce={login_nonce}" f"×tamp={login_timestamp}" f"&signature={quote(login_signature, safe='')}" f"&s_url={quote(target_url, safe='')}" ) ``` ### Technical Analysis The target is copied directly from a command-line argument into the signed Tencent login callback URL. The script does not parse the URL or restrict its scheme, hostname, port, path, query parameters, or user-information component. This allows the trusted Tencent login domain to be used as the visible entry point for a redirect to an arbitrary destination. Even if Tencent ultimately applies additional server-side restrictions, the client does not enforce the Skill's documented boundary of Advisor pages under `console.cloud.tencent.com`. ### Attack Path 1. An attacker persuades a user or Agent to generate a link with an attacker-controlled target URL. 2. The script creates a legitimate-looking `https://cloud.tencent.com/login/roleAccessCallback?...` URL. 3. The user trusts the Tencent hostname and opens the link. 4. After the login callback, the browser is directed to the attacker-supplied destination. 5. The attacker presents a phishing page, requests additional credentials, or performs another social-enginee ...[truncated 250 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/setup_role.py:388
Finding

Role Setup Can Select Arbitrary Console Roles Without Permission Validation

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/cleanup.py:282
Finding

Cleanup Can Delete an Unrelated Pre-Existing CAM Role Without Ownership Verification

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:24
Finding

Documentation Directs Users to Persist Long-Lived Cloud Credentials in Plaintext Shell Files

Content
View full analysis
> ~/.bashrc echo 'export TENCENTCLOUD_SECRET_KEY="your-secret-key"' >> ~/.bashrc source ~/.bashrc ``` The environment-check script repeats the same instructions: ```python log_info( " Please permanently write Tencent Cloud API credentials " "to a shell configuration file:" ) log_info( ' echo \'export TENCENTCLOUD_SECRET_ID="your-secret-id"\' ' '>> ~/.bashrc' ) log_info( ' echo \'export TENCENTCLOUD_SECRET_KEY="your-secret-key"\' ' '>> ~/.bashrc' ) log_info(" source ~/.bashrc") ``` ### Technical Analysis Shell startup files are plaintext and are loaded by interactive shell sessions. The Skill instructs users that credentials must be stored permanently rather than presenting persistence as an optional tradeoff. The process does not check or harden the startup file's permissions. Such files may be included in workstation backups, support bundles, dotfile repositories, synchronization systems, or accidental disclosures. Every child process launched from the shell may also inherit the credentials. The cleanup script cannot remove persisted entries automatically; it only tells users to edit startup files manually. ### Attack Path 1. A user follows the mandatory setup instructions and writes long-lived SecretId and SecretKey values to `~/.bashrc` or `~/.zshrc`. 2. The file is read by another local process, copied into a backup, committed to a dotfile repository, or included in diagnostic output. 3. An attacker obtains the credentials. 4. The attacker authenticates to Tencent Cloud with the privileges assigned to the underlying identity. 5. Access persists until the credentials are rotated or revoked. ### Impact Assessment Compromise affects e ...[truncated 223 chars]
Remediation
View remediation

other

Warning
Location
check_env.py:73
Finding

Read-Only and Network Security Declarations Contradict Actual Side Effects

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (42)

Tainted flow: 'req' from os.environ.get (line 228, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/login_url.py (reported line 236)May include surrounding context.

python
)

    ctx = _get_ssl_context()
    with urlopen(req, context=ctx) as resp:
        result = json.loads(resp.read().decode("utf-8"))

    response_body = result.get("Response", {})

Tainted flow: 'req' from os.environ.get (line 186, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/tcloud_api.py (reported line 195)May include surrounding context.

python
try:
        ctx = _get_ssl_context()
        with urlopen(req, context=ctx, timeout=30) as resp:
            response_body = resp.read().decode("utf-8")
    except HTTPError as e:
        try:

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill also enumerates roles, tests role assumption, writes local configuration, and performs IAM-related setup while being framed mainly as a TSA inspection utility. This mismatch is risky because it obscures the real privilege footprint and operational effects of the tool, especially in environments where cloud IAM changes require heightened scrutiny.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also enumerates roles, tests role assumption, writes local configuration, and performs IAM-related setup while being framed mainly as a TSA inspection utility. This mismatch is risky because it obscures the real privilege footprint and operational effects of the tool, especially in environments where cloud IAM changes require heightened scrutiny.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill also enumerates roles, tests role assumption, writes local configuration, and performs IAM-related setup while being framed mainly as a TSA inspection utility. This mismatch is risky because it obscures the real privilege footprint and operational effects of the tool, especially in environments where cloud IAM changes require heightened scrutiny.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill also enumerates roles, tests role assumption, writes local configuration, and performs IAM-related setup while being framed mainly as a TSA inspection utility. This mismatch is risky because it obscures the real privilege footprint and operational effects of the tool, especially in environments where cloud IAM changes require heightened scrutiny.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill also enumerates roles, tests role assumption, writes local configuration, and performs IAM-related setup while being framed mainly as a TSA inspection utility. This mismatch is risky because it obscures the real privilege footprint and operational effects of the tool, especially in environments where cloud IAM changes require heightened scrutiny.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

��变量配置密钥:

1.1 必填环境变量

  • TENCENTCLOUD_SECRET_ID — 腾讯云 SecretId(必填)
  • TENCENTCLOUD_SECRET_KEY — 腾讯云 SecretKey(必填)

密钥获取地址:https://console.cloud.tencent.com/cam/capi

环境变量必须永久写入 shell 配置文件,确保新会话中仍然生效:

Linux / macOS(写入 ~/.bashrc 或 ~/.zshrc):

bash
echo 'export TENCENTCLOUD_SECRET_ID="your-secret-id"' >> ~/.bashrc
echo 'export TENCENTCLOUD_SECRET_KEY="your-secret-key"' >> ~/.bashrc
source ~/.bashrc

Windows PowerShell(写入用户级环境变量):

powershell
[Environment]::SetEnvironmentVariable("TENCENTCLOUD_SECRET_ID", "your-secret-id", "User")
[Environment]::SetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY", "your-secret-key", "User")

1.2 角色配置(免密登录需要)

为生成控制台免密登录链接,需要配置 CAM 角色。角色配置分为 检测 和 创建 两个独立步骤,角色创

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · check_env.py (reported line 261)May include surrounding context.

python
nd("TENCENTCLOUD_SECRET_ID")
        if not secret_key:
            missing.append("TENCENTCLOUD_SECRET_KEY")
        log_fail(f"未配置以下环境变量: {', '.join(missing)}")
        log_info("")
        log_info("  请将腾讯云 API 密钥永久写入 shell 配置文件:")
        log_info("")
        log_info("  Linux / macOS(写入 ~/.bashrc 或 ~/.zshrc):")
        log_info('    echo \'export TENCENTCLOUD_SECRET_ID="your-secret-id"\' >> ~/.bashrc')
        log_info('    echo \'export TENCENTCLOUD_SECRET_KEY="your-secret-key"\' >> ~/.bashrc')
        log_info("    source ~/.bashrc")
        log_info("")
        log_info("  Windows PowerShell(写入用户级环境变量):")
        log_info('    [Environment]::SetEnvironmentVariable("TENCENTCLOUD_SECRET_ID", "your-secret-id", "User")')
        log_info('    [Environment]::SetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY", "your-secret-key", "User")')
        log_info("")
        log_info("  密钥获取地址: https:

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script contains cloud-side destructive capability to delete a CAM role named "advisor" when run with --cloud and valid credentials. In a skill advertised primarily as architecture risk inspection, adding IAM-role deletion increases blast radius and could remove legitimate access configuration if a user runs cleanup with broad AK/SK credentials, especially because the role name is generic and not strongly bound to resources created by this tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script performs IAM write operations by creating a CAM role and attaching broad managed policies, which exceeds the skill’s stated read-only architecture risk-inspection purpose. In an agent-skill context, bundled privilege-granting automation is dangerous because it can modify a user’s cloud access model and create persistent access paths if invoked with available credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

If certifi is unavailable, the script disables TLS certificate validation and hostname checking for outbound HTTPS requests. This permits man-in-the-middle interception or tampering of STS responses, which could expose temporary credentials, alter returned data, or redirect the authentication flow.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · scripts/setup_role.py (reported line 44)May include surrounding context.

python
if platform.system() == "Windows":
        # Windows 10+ 的 cmd/PowerShell 支持 ANSI(需 VT100)
        try:
            os.system("")  # 激活 VT100 模式
            return True
        except Exception:
            return False

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This setup script performs privileged CAM/IAM state changes—creating a role and modifying policy attachments—even though the skill metadata describes a read/query-oriented advisor tool. That mismatch is dangerous because users may authorize credentialed execution expecting inspection only, while the script actually persists new access pathways and changes cloud identity configuration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code auto-creates a console-login role and attaches broad managed policies (QcloudTAGFullAccess, QcloudAdvisorFullAccess), expanding privileges beyond the minimum needed for simple advisor queries. If run with sufficiently privileged credentials, this can create durable, unnecessary access that increases blast radius and could be abused later for reconnaissance or administrative misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

If certifi is unavailable, the code disables hostname checking and certificate validation entirely, causing HTTPS connections to trust any certificate. Because this client sends signed cloud API requests carrying sensitive authentication material, an on-path attacker could intercept or redirect requests, capture metadata, and potentially replay or abuse temporary credentials.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs users to persist long-lived cloud API secrets in shell startup files and user-level environment settings. Persisting high-value credentials in broadly readable or routinely sourced profile locations increases the risk of credential theft via local compromise, backups, shell history mishandling, shared-user systems, or accidental disclosure during troubleshooting.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The role-creation guidance is internally inconsistent: one section claims the role only grants Advisor read-only access, while another later proposes attaching broader TAG/Advisor FullAccess permissions. Such contradictory security documentation can mislead users into approving overprivileged IAM changes under the false impression that access is narrowly limited.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file defines invocation trigger phrases, so SQP-1 applies. Among the listed triggers for DescribeStrategies, "安全检查" is generic and could match many unrelated security-check requests, increasing the chance of unintended activation without clear exclusion conditions or tighter scope.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file header claims the script is read-only and does not modify configuration, but the code later writes ~/.tsa-risk/config.json when it detects an existing role. This misleading behavior can cause users or calling automation to grant trust or execute the script under assumptions that no local state will be changed, which is dangerous in security-sensitive setup tooling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file-level docstring and all user-facing operational messages are written exclusively in Chinese, which imposes a language choice on users without any opt-in or alternative locale. The policy explicitly calls for flagging language or locale constraints when the skill does not offer a user choice or clearly justify the restriction.

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 · check_env.py (reported line 141)May include surrounding context.

python
"""
    import subprocess
    try:
        result = subprocess.run(
            ["clawhub", "inspect", slug, "--json"],
            capture_output=True, text=True, timeout=VERSION_CHECK_TIMEOUT,
        )

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 · check_env.py (reported line 404)May include surrounding context.

python
login_url_path = SCRIPT_DIR / "login_url.py"

            import subprocess
            test_result = subprocess.run(
                [sys.executable, str(login_url_path),
                 "https://console.cloud.tencent.com/advisor"],
                capture_output=True, text=True, timeout=30,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill handles a user identifier and explicitly instructs generation of passwordless console login links for architecture resources, but provides no warning, consent, scope limitation, or safe-handling guidance. In this context, the returned architecture details may expose sensitive cloud topology and resource identifiers, and the mandatory regeneration/display of direct-access links increases the chance of unintended privileged access or link leakage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.