Back to skill

Security audit

禅道自动报告

Security checks for vulnerabilities and agentic risk

Overview

This skill fits its ZenTao time-reporting purpose, but it handles login secrets and active sessions unsafely enough that users should review it before installing.

Install only if you are comfortable giving this skill access to a ZenTao account that can read tasks and modify work-hour records. Before use, require HTTPS for ZENTAO_URL, stop logging zentaosid values, store credentials in a protected secret store or chmod 600 file, avoid the shell fallback until curl --form-string is used, and rotate any credentials or sessions that may already have appeared in logs.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/report.sh:75
Finding

Local File Disclosure Through curl Multipart Form Interpretation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report.py:40
Finding

Credentials and Session Data May Be Transmitted Over Plaintext HTTP

Content
View full analysis
/dev/null curl -b /tmp/cookies.txt -c /tmp/cookies.txt "$ZENTAO_URL/index.php?m=user&f=login&t=json" \ -X POST \ -d "account=$ZENTAO_ACCOUNT&password=$ZENTAO_PASSWORD&remember=on" \ -H "Content-Type: application/x-www-form-urlencoded" \ -s > /dev/null TASK_INFO=$(curl "$ZENTAO_URL/api.php/v1/tasks/$TASK_ID" \ -H "Token: $ZENTAO_TOKEN" -s) ``` ### Technical Analysis `ZENTAO_URL` comes from the local configuration and is only normalized to end with `/`. None of the implementations require an `https://` scheme. If the URL uses `http://`, the account password, API token, session cookie, task information, and submitted work descriptions can cross the network without transport encryption. An active network attacker may also alter server responses ...[truncated 1117 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report.py:156
Finding

Active ZenTao Session Identifiers Are Written to Console and Agent Logs

Content
View full analysis
>> Re-login to get fresh zentaosid...") zentaosid = relogin(zentao_url, zentao_account, zentao_password) print(f">>> Got fresh zentaosid: {zentaosid}") ``` From `scripts/match-tasks.py`: ```python print(">>> No zentaosid found, re-login...") zentaosid = relogin(zentao_url, zentao_account, zentao_password) print(f">>> Got fresh zentaosid: {zentaosid}") ``` From `scripts/report.sh` and `scripts/match-tasks.sh`: ```bash ZENTAO_SID=$(grep 'zentaosid' /tmp/cookies.txt | tail -1 | awk '{print $7}') echo ">>> Got fresh zentaosid: $ZENTAO_SID" ``` ### Technical Analysis A `zentaosid` is an authentication bearer secret. Any party possessing a valid value may be able to issue authenticated ZenTao requests without knowing the user's password. All implementations print the full session identifier after authentication. In an agent environment, standard output may be retained in conversation transcripts, execution logs, observability platforms, CI logs, or debugging records. This needlessly expands access to the session beyond the process performing the requested operation. ### Attack Path 1. The Skill authenticates to ZenTao and obtains a valid `zentaosid`. 2. The script writes the complete value to standard output. 3. The output is retained in an agent transcript, terminal history, CI log, or centralized logging system. 4. A person or service with access to those logs extracts the identifier. 5. The identifier is replayed as a `zentaosid` cookie against ZenTao before it expires or is invalidated. ### Impact Assessment A log reader can potentially hijack the victim's active ZenTao session. The resulting scope is bounded by the victim's Z ...[truncated 123 chars]
Remediation
View remediation
>> Authentication succeeded") ``` ```bash echo ">>> Authentication succeeded" ``` Also: - Treat session IDs, passwords, and tokens as secrets in the logging policy. - Add automated secret-redaction filters as defense in depth. - Avoid including complete HTTP responses in logs if those responses can contain credentials or private data. - Invalidate previously exposed sessions and rotate affected credentials where logs have already retained session values. - Add tests that fail if output contains values matching known session-secret fields. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report.sh:30
Finding

Predictable Shared Temporary Cookie File Enables Session Leakage and File-System Races

Content
View full analysis
/dev/null curl -b /tmp/cookies.txt -c /tmp/cookies.txt "$ZENTAO_URL/index.php?m=user&f=login&t=json" \ -X POST \ -d "account=$ZENTAO_ACCOUNT&password=$ZENTAO_PASSWORD&remember=on" \ -H "Content-Type: application/x-www-form-urlencoded" \ -s > /dev/null ZENTAO_SID=$(grep 'zentaosid' /tmp/cookies.txt | tail -1 | awk '{print $7}') ``` The Python matcher later trusts the same global path: ```python cookie_file = Path('/tmp/cookies.txt') if cookie_file.exists(): with open(cookie_file) as f: for line in f: if 'zentaosid' in line: parts = line.strip().split() if len(parts) >= 7: zentaosid = parts[6] ``` ### Technical Analysis The shell scripts store authentication cookies at the fixed path `/tmp/cookies.txt`. A global predictable filename creates several problems: - Concurrent runs can overwrite or consume each other's sessions. - A stale cookie can be reused by a later Python invocation. - Another local process may pre-create or replace the path. - Depending on platform behavior and protections, a symbolic-link attack could redirect writes toward another file available to the victim process. - The file is not explicitly deleted after use. - The scripts do not explicitly establish mode `0600`. The Python implementation compounds the issue by treating any suitably formatted `zentaosid` found in that global file as trusted authentication state. ### Attack Path A session-confusion or disclosure path is: 1. One Skill invocation authenticates and writes a live session cookie to `/tmp/cookies.txt`. 2. The file ...[truncated 993 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/report.sh:9
Finding

Plaintext Credential Configuration Is Used Without Permission Enforcement

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A second independently identified description-behavior mismatch indicates the skill may not actually perform the promised task search, intelligent matching, or confirmation flow, and instead requires explicit task IDs. While this is less directly severe than secret access, it still creates a trust and integrity problem because users may believe the agent is safely deriving and confirming the correct task before submitting worklog data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A second independently identified description-behavior mismatch indicates the skill may not actually perform the promised task search, intelligent matching, or confirmation flow, and instead requires explicit task IDs. While this is less directly severe than secret access, it still creates a trust and integrity problem because users may believe the agent is safely deriving and confirming the correct task before submitting worklog data.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/match-tasks.py (reported line 14)May include surrounding context.

python
from pathlib import Path
from datetime import datetime

CONFIG_PATH = Path.home() / ".config" / "zentao" / ".env"

def load_config():
    """加载配置文件"""

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints a freshly obtained session identifier directly to stdout, which can expose an active authenticated session in terminal scrollback, logs, agent transcripts, or CI output. Anyone who obtains that token may be able to impersonate the user to the ZenTao instance until the session expires or is revoked.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The script loads secrets from a local .env file using export $(cat ... | xargs), which is unsafe and can misparse values, expose secrets to child processes, and trust unvalidated local configuration as code-like input. Because this skill handles ZenTao credentials and session state, compromise of that file or weak permissions would directly enable account takeover or redirection of requests to malicious endpoints.

Content

Scanner excerpt · scripts/match-tasks.sh (reported line 10)May include surrounding context.

sh
set -e

# 加载配置
CONFIG_FILE="$HOME/.config/zentao/.env"
if [ -f "$CONFIG_FILE" ]; then
    export $(cat "$CONFIG_FILE" | xargs)
else

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/match-tasks.sh (reported line 42)May include surrounding context.

sh
# 获取当前用户所有任务
echo ">>> Fetching all tasks..."
RESPONSE=$(curl -b "zentaosid=$ZENTAO_SID" "$ZENTAO_URL/index.php?m=my&f=task&t=json&onlybody=yes" \
  -H "X-Requested-With: XMLHttpRequest" \
  -s)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/match-tasks.sh (reported line 42)May include surrounding context.

sh
# 获取当前用户所有任务
echo ">>> Fetching all tasks..."
RESPONSE=$(curl -b "zentaosid=$ZENTAO_SID" "$ZENTAO_URL/index.php?m=my&f=task&t=json&onlybody=yes" \
  -H "X-Requested-With: XMLHttpRequest" \
  -s)

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The script is designed to load secrets, including account credentials and tokens, from a plaintext .env file under the user's home directory. Storing long-lived credentials in a predictable local file raises the risk of credential theft through local compromise, backup leakage, misconfigured file permissions, or accidental inclusion in support bundles.

Content

Scanner excerpt · scripts/report.py (reported line 14)May include surrounding context.

python
from datetime import datetime
from pathlib import Path

CONFIG_PATH = Path.home() / ".config" / "zentao" / ".env"

def load_config():
    """加载配置文件"""

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The script loads secrets from ~/.config/zentao/.env using export $(cat "$CONFIG_FILE" | xargs), which is an unsafe parsing pattern for shell data. Malformed values, whitespace, special characters, or attacker-influenced content in the file can corrupt environment variables or alter script behavior, and storing reusable credentials locally also raises compromise risk if the file is accessible to other users.

Content

Scanner excerpt · scripts/report.sh (reported line 10)May include surrounding context.

sh
set -e

# 加载配置
CONFIG_FILE="$HOME/.config/zentao/.env"
if [ -f "$CONFIG_FILE" ]; then
    export $(cat "$CONFIG_FILE" | xargs)
else

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/report.sh (reported line 42)May include surrounding context.

sh
# 获取当前任务信息,计算新的left
echo ">>> Getting task info for $TASK_ID..."
TASK_INFO=$(curl "$ZENTAO_URL/api.php/v1/tasks/$TASK_ID" \
  -H "Token: $ZENTAO_TOKEN" -s)

CURRENT_LEFT=$(echo "$TASK_INFO" | python3 -c "

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill declares behavior that clearly requires network access and script execution, but it does not declare any explicit tool scope or allowed tools. This weakens least-privilege controls and makes it harder for users or the hosting platform to understand and constrain what the skill may do before handling credentials and contacting external systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs users to persist a ZenTao password and optional API token in a local .env file under the home directory without clearly warning about credential-at-rest risk or describing file-permission protections. Storing long-lived secrets in plaintext increases the chance of credential theft by other local users, malware, backups, or accidental disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The header describes a low-risk read/match utility, but the implementation also performs automatic login with stored credentials. That mismatch is dangerous because users, reviewers, and calling agents may authorize or execute the script under false assumptions about what sensitive actions it performs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script submits account credentials in an HTTP request without enforcing that the configured URL uses HTTPS. In this skill context, that means passwords could be sent over an insecure network or to a downgraded endpoint, enabling interception by local network attackers or proxies.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script reads authentication material from both a persistent config file and a world-accessible temporary location, even though its user-facing purpose is only task retrieval and matching. This unnecessarily broadens access to credential/session data and increases the chance of token theft, session fixation, or accidental leakage through local files and downstream tooling.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This code transmits stored credentials to a remote endpoint using curl, which is expected for logging into ZenTao, but it still creates security risk because the destination URL is fully controlled by configuration and there is no validation that it is HTTPS or trusted. In an agent skill context, misconfiguration or tampering with ZENTAO_URL could cause credential exfiltration to an attacker-controlled server.

Content

Scanner excerpt · scripts/match-tasks.sh (reported line 29)May include surrounding context.

sh
# 如果 ZENTAO_SID 未设置,尝试通过登录获取
if [ -z "$ZENTAO_SID" ]; then
    echo ">>> ZENTAO_SID not set, re-login to get fresh zentaosid..."
    curl -c /tmp/cookies.txt "$ZENTAO_URL/user-login.html" -s > /dev/null
    curl -b /tmp/cookies.txt -c /tmp/cookies.txt "$ZENTAO_URL/index.php?m=user&f=login&t=json" \
      -X POST \
      -d "account=$ZENTAO_ACCOUNT&password=$ZENTAO_PASSWORD&remember=on" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script prints a freshly obtained ZenTao session identifier directly to stdout. Session IDs are bearer tokens; exposing them in terminal output, logs, chat transcripts, or agent tool traces can allow anyone who sees the value to hijack the authenticated session and act as the user.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script reads a stored username and password and performs an interactive login flow to obtain a session cookie, even though it also uses an API token elsewhere. This expands credential exposure and privilege scope beyond the minimum needed, increasing the risk of account compromise if the config file, process environment, logs, or network path are exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script prints the fresh zentaosid session token directly to stdout, which can leak into terminal history, CI logs, agent transcripts, shell capture systems, or centralized logging. Anyone with access to that output may be able to replay the session and act as the user within Zentao.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script loads and exports values from a local .env file, which are later used as credentials and tokens. There is no explicit warning, comment, or usage text telling the user that sensitive configuration values will be read from disk and used for authentication.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The script sends account credentials and session material over network requests to whatever endpoint is placed in ZENTAO_URL, with no validation that the URL uses HTTPS or points to a trusted host. If the URL is misconfigured, attacker-controlled, or uses plain HTTP, credentials can be intercepted or exfiltrated; additionally, the script prints the fresh session ID to stdout, increasing exposure.

Content

Scanner excerpt · scripts/report.sh (reported line 30)May include surrounding context.

sh
# 重新登录获取最新有效的zentaosid
echo ">>> Re-login to get fresh zentaosid..."
curl -c /tmp/cookies.txt "$ZENTAO_URL/user-login.html" -s > /dev/null
curl -b /tmp/cookies.txt -c /tmp/cookies.txt "$ZENTAO_URL/index.php?m=user&f=login&t=json" \
  -X POST \
  -d "account=$ZENTAO_ACCOUNT&password=$ZENTAO_PASSWORD&remember=on" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code performs login HTTP requests and sends the username and password from environment variables to the remote Zentao server. While the script logs that it is re-authenticating, it does not warn the user that stored credentials will be used and transmitted, and there is no doc comment explaining this sensitive behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The header comment presents the script as simply '自动记录一条工时' with usage focused on reporting hours. In practice, the code also loads credentials, performs a fresh login to obtain a session, and queries task information to recompute remaining hours before submission. This is an active mismatch between the script's documentation and its implemented behavior, not merely omitted detail.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file includes natural-language descriptions and messages in Chinese, such as the header comment and docstrings, without any indication that the skill is region-specific or that users can opt into that locale. Under the stated policy, forcing a specific language without user choice or justification is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script includes Chinese-only natural-language descriptions and comments such as the title line, with no indication that the locale is optional or intentionally limited to a specific audience. Under the policy, forcing a specific language without user opt-in can be a locale-policy violation.

Content

No source excerpt is available for this finding.