T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/report.sh:75- Finding
Local File Disclosure Through curl Multipart Form Interpretation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
scripts/report.sh:75Local File Disclosure Through curl Multipart Form Interpretation
scripts/report.py:40Credentials and Session Data May Be Transmitted Over Plaintext HTTP
scripts/report.py:156Active ZenTao Session Identifiers Are Written to Console and Agent Logs
scripts/report.sh:30Predictable Shared Temporary Cookie File Enables Session Leakage and File-System Races
scripts/report.sh:9Plaintext Credential Configuration Is Used Without Permission Enforcement
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.
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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
from pathlib import Path
from datetime import datetime
CONFIG_PATH = Path.home() / ".config" / "zentao" / ".env"
def load_config():
"""加载配置文件"""
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.
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.
set -e
# 加载配置
CONFIG_FILE="$HOME/.config/zentao/.env"
if [ -f "$CONFIG_FILE" ]; then
export $(cat "$CONFIG_FILE" | xargs)
else
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# 获取当前用户所有任务
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)
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# 获取当前用户所有任务
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)
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.
from datetime import datetime
from pathlib import Path
CONFIG_PATH = Path.home() / ".config" / "zentao" / ".env"
def load_config():
"""加载配置文件"""
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.
set -e
# 加载配置
CONFIG_FILE="$HOME/.config/zentao/.env"
if [ -f "$CONFIG_FILE" ]; then
export $(cat "$CONFIG_FILE" | xargs)
else
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
# 获取当前任务信息,计算新的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 "
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.
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.
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.
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.
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.
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.
# 如果 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" \
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.
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.
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.
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.
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.
# 重新登录获取最新有效的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" \
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.
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.
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.
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.