Back to skill

Security audit

skill-d-create-issues

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent meeting-to-Gitea workflow, but it ships insecure defaults that can expose tokens, accept forged webhook events, and run unsafe setup code.

Review this skill before installing. Use only an HTTPS Gitea endpoint, require a strong webhook secret, avoid exposing the listener publicly, do not run setup.sh against untrusted .env content, prefer a virtual environment with pinned dependencies, and confirm generated issues and emails before sending or publishing.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (6)

T09 · Insecure Skill Coding Practices

Error
Location
env-example.txt:2
Finding
Gitea Bot Token Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `env-example.txt:2`, `scripts/gitea_utils.py:9-15`, `scripts/log_utils.py:13-18` **Vulnerability Type**: Cleartext transmission of credentials **Risk Level**: High ### Vulnerable Code ```text # env-example.txt GITEA_BASE_URL=http://43.156.243.152:3000 ``` ```python # scripts/gitea_utils.py def gitea_request(method, path, token, base_url, raise_on_error=True, **kwargs): url = f"{base_url.rstrip('/')}/api/v1{path}" headers = { "Authorization": f"token {token}", "Content-Type": "application/json", } resp = requests.request(method, url, headers=headers, timeout=15, **kwargs) ``` ```python # scripts/log_utils.py api_url = f"{base_url.rstrip('/')}/api/v1/repos/{owner}/{repo_name}/contents/{filepath}" headers = { "Authorization": f"token {token}", "Content-Type": "application/json", } existing_content = "" existing_sha = None resp = requests.get(api_url, headers=headers, timeout=10) ``` ### Technical Analysis The example configuration directs all Gitea API traffic to a public IP address using unencrypted HTTP. The API helpers place the Gitea bot token in the `Authorization` header for every request. HTTP provides neither transport confidentiality nor server authentication. A network adversary can observe the token, alter API responses, or redirect workflow operations. Base64 encoding used by the Gitea Contents API does not provide encryption and does not mitigate this exposure. Access to a local credential file is necessary for the declared Gitea integration. The vulnerability is not the file access itself, but transmitting the loaded credential over an insecure transport. ### Attack Path 1. A user copies the provided example configuration and supplies a valid bot token. 2. The Skill invokes `check`, `create-issues`, or `finish`. 3. The API helper sends `Authorization: token <GITEA_TOKEN_BOT>` over plaintext HTTP. 4. An attacker with network visibility captures the ...[truncated 574 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the default URL with an HTTPS endpoint backed by a valid certificate. - Reject `http://` Gitea URLs at startup rather than silently accepting them. - Validate the destination hostname against an administrator-configured allowlist. - Use a dedicated, narrowly scoped bot token with access only to required repositories and operations. - Rotate the existing token if it has ever been used with the plaintext endpoint. - Consider certificate pinning or an internal trusted CA where the deployment environment requires stronger endpoint assurance. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/webhook.py:34
Finding
Webhook Listener Accepts Unauthenticated Events by Default<![CDATA[ ## Vulnerability Details **File Location**: `env-example.txt:12`, `scripts/webhook.py:34-47`, `scripts/webhook.py:84-110`, `scripts/webhook.py:136` **Vulnerability Type**: Missing authentication on a network-exposed webhook **Risk Level**: High ### Vulnerable Code ```text # env-example.txt WEBHOOK_SECRET= ``` ```python # scripts/webhook.py WEBHOOK_PORT = int(os.getenv("WEBHOOK_PORT", "8765")) WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "").encode() def verify_signature(payload_bytes: bytes, signature_header: str) -> bool: """验证 Gitea HMAC-SHA256 签名(WEBHOOK_SECRET 为空时跳过验证)。""" if not WEBHOOK_SECRET: return True if not signature_header: return False ``` ```python @app.route("/gitea-webhook", methods=["POST"]) def gitea_webhook(): payload_bytes = request.get_data() sig = request.headers.get("X-Gitea-Signature", "") if not verify_signature(payload_bytes, sig): abort(403) event = request.headers.get("X-Gitea-Event", "") if event != "push": return "ignored", 200 try: payload = json.loads(payload_bytes) except Exception: abort(400) triggers = extract_triggers(payload) for trigger in triggers: signal = { "ts": datetime.now(TZ).isoformat(), "event": "confirmed_issue_detected", "repo": trigger["repo"], "meeting_dir": trigger["meeting_dir"], } line = f"SKILL_D_TRIGGER: {json.dumps(signal, ensure_ascii=False)}" print(line, flush=True) ``` ```python app.run(host="0.0.0.0", port=WEBHOOK_PORT, debug=False) ``` ### Technical Analysis The supplied configuration leaves `WEBHOOK_SECRET` empty. When it is empty, `verify_signature` unconditionally accepts requests. The Flask service also binds to `0.0.0.0`, making it reachable through every available network interface unless an external firewall blocks access. An unauthenticated client can therefore submit a for ...[truncated 1431 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Make `WEBHOOK_SECRET` mandatory and terminate startup when it is absent or weak. - Generate a high-entropy secret and configure the identical value in Gitea. - Retain constant-time HMAC comparison, but verify the precise signature format supported by the deployed Gitea version. - Bind the service to a private or loopback interface where possible. - Restrict inbound traffic to trusted Gitea source addresses using a firewall or reverse proxy. - Add replay resistance by validating delivery identifiers or timestamps and retaining recently processed event IDs. - Validate the repository against an explicit allowlist before emitting a trigger. - Place the endpoint behind HTTPS to protect webhook payload integrity and confidentiality. ]]>

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:86
Finding
Repository-Controlled Content Can Indirectly Hijack Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:86-119`, `scripts/check.py:75-87`, `scripts/check.py:112-127` **Vulnerability Type**: Indirect prompt injection through untrusted repository content **Risk Level**: High ### Vulnerable Code and Instructions ```markdown ### 第二步:OpenClaw 解析 confirmed_issue.md **此步骤 OpenClaw 作为 AI 负责全部解析,不调用任何脚本。** 从 `confirmed_issue_content` 中解析每条带勾选框的 action item,输出 JSON 数组, **只输出 JSON,不加任何说明文字或 markdown 标记**: ``` ```python confirmed_content, _ = get_file_from_repo( owner, repo_name, confirmed_path, GITEA_TOKEN, GITEA_BASE_URL ) if not confirmed_content: _invalid("confirmed_issue.md 内容为空,请检查文件是否正确上传。") ``` ```python print(json.dumps({ "valid": True, "repo": args.repo, "meeting_dir": d, "category": meta.get("meeting_category", "single"), "topic": meta.get("topic", ""), "scheduled_time": meta.get("scheduled_time", ""), "join_url": meta.get("join_url", ""), "organizer": organizer, "organizer_email": organizer_email, "attendees": attendees, "attendee_emails": attendee_emails, "confirmed_issue_content": confirmed_content, "minutes_content": minutes_content or "", }, ensure_ascii=False, indent=2)) ``` ### Technical Analysis The workflow passes repository-controlled Markdown directly to an AI Agent and instructs the Agent to interpret it. No strict parser, schema boundary, or explicit instruction/data separation prevents text inside `confirmed_issue.md` from being interpreted as new instructions. An attacker with repository write access—or an attacker who can influence content merged into the repository—can place prompt-injection text in the meeting document. The Agent may then generate attacker-selected issue fields or depart from the intended extraction task. The unauthenticated webhook ...[truncated 1344 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace free-form model parsing with a deterministic parser and a documented machine-readable schema. - Validate the parsed result against a strict JSON Schema before any Gitea mutation. - Enforce length, character, date, username, and dependency constraints for every field. - Treat repository documents as untrusted data and clearly delimit them from Agent instructions. - Add an explicit system-level rule that instructions found inside meeting files must never be followed. - Require a human confirmation step showing the exact issues, assignees, and repository before creation. - Confirm that every assignee is an allowed repository member and every dependency references a unique local item. - Limit the Agent's tools during parsing so it cannot perform unrelated operations. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
setup.sh:30
Finding
Setup Script Executes the Dotenv Configuration as Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `setup.sh:30` **Vulnerability Type**: Arbitrary command execution through unsafe configuration parsing **Risk Level**: High ### Vulnerable Code ```bash echo "" echo "🔍 检查配置..." set -a; source "$ENV_FILE"; set +a ``` ### Technical Analysis The setup script uses Bash `source` to load a file intended to contain dotenv configuration. `source` does not parse the file as inert `KEY=VALUE` data; it executes the entire file as shell code in the current process. Consequently, command substitutions, function calls, redirections, and arbitrary shell statements added to the file execute with the privileges of the user running `setup.sh`. File mode `0600` reduces access by other local users but does not protect against configuration replacement, compromised backups, malicious provisioning, or social engineering that persuades the operator to paste hostile content. ### Attack Path 1. An attacker modifies the `.env` file or provides a malicious configuration fragment to the operator. 2. The malicious file includes a command such as a command substitution or standalone shell statement. 3. The operator reruns `bash setup.sh` to validate or update the installation. 4. Bash evaluates `source "$ENV_FILE"`. 5. The attacker's command executes as the operator before the required-variable checks occur. ### Impact Assessment Successful exploitation provides arbitrary local command execution with the privileges of the user running setup. This can expose the Gitea token and other user files, alter project or shell configuration, install user-level persistence, or tamper with local tools. If the setup script is run with elevated privileges, the impact expands to the corresponding administrative scope. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Never load dotenv files using `source`, `.`, or `eval`. - Parse the file with a non-executing dotenv library or a small parser that accepts only explicitly named keys. - Reject malformed lines, duplicate keys, shell metacharacters, command substitutions, and unexpected variable names. - Prefer invoking a Python configuration-validation script that uses `python-dotenv`. - Verify ownership and restrictive permissions before reading the configuration. - Document that secrets must not be supplied through untrusted configuration snippets. ]]>

T08 · Insecure Dependencies

Warning
Location
setup.sh:11
Finding
Unpinned Dependencies Are Installed into the System Python Environment<![CDATA[ ## Vulnerability Details **File Location**: `setup.sh:11-14`, `requirements.txt:1-6` **Vulnerability Type**: Unsafe dependency installation and insufficient version integrity controls **Risk Level**: Medium ### Vulnerable Code ```bash echo "📦 安装 Python 依赖..." pip install -r "$SKILL_DIR/requirements.txt" --break-system-packages -q echo "✅ Python 依赖安装完成" ``` ```text requests>=2.28.0 python-dotenv>=1.0.0 PyYAML>=6.0 pytz>=2023.3 python-dateutil>=2.8.2 flask>=3.0.0 ``` ### Technical Analysis Every dependency uses an open-ended lower-bound constraint. A future release satisfying the constraint can be installed without review, and no hashes authenticate the exact artifacts. The script also uses `--break-system-packages`, bypassing protections intended to prevent pip from modifying an externally managed Python installation. The reviewed package names are established packages, and no specific malicious dependency was identified. The risk arises from unconstrained future versions, lack of artifact integrity pinning, and modification of a shared interpreter environment. ### Attack Path 1. The operator runs `setup.sh` at a later date. 2. pip resolves the newest releases satisfying the open-ended constraints. 3. A compromised, malicious, or unexpectedly incompatible release is selected. 4. Installation modifies the system Python environment because `--break-system-packages` is enabled. 5. Installation-time behavior or later imports execute the affected package code. 6. The Skill or unrelated Python applications inherit the compromised or incompatible dependency. ### Impact Assessment A malicious dependency executes with the installing user's privileges and can access the local Gitea credential, repository data handled by the Skill, and other user files. Even without malicious code, dependency conflicts can break system utilities or unrelated applications using the same interpreter. The issue does not establish that any currently listed package is malici ...[truncated 8 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create and use a dedicated virtual environment for the Skill. - Pin every direct and transitive dependency to an exact reviewed version. - Use a lock file or requirements file containing SHA-256 hashes and install with `--require-hashes`. - Remove `--break-system-packages`. - Configure pip to use an approved package index and require TLS. - Add automated dependency vulnerability and update review. - Rebuild and test the lock file deliberately rather than resolving newest versions during production setup. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/email_utils.py:40
Finding
Unescaped Meeting Data Is Embedded in Generated Email HTML<![CDATA[ ## Vulnerability Details **File Location**: `scripts/email_utils.py:40-104`, `scripts/email_utils.py:164-184`, `scripts/email_utils.py:236-266` **Vulnerability Type**: HTML injection in generated email content **Risk Level**: Medium ### Vulnerable Code ```python issue_rows = "".join( f'<tr>' f'<td style="padding:8px 12px;border:1px solid #e0e0e0;">' f'<a href="{i["issue_url"]}" style="color:#1a73e8;">#{i["issue_number"]}</a></td>' f'<td style="padding:8px 12px;border:1px solid #e0e0e0;">{i["task"]}</td>' f'<td style="padding:8px 12px;border:1px solid #e0e0e0;">@{i["assignee"]}</td>' f'</tr>' for i in created_issues ) ``` ```python if minutes_content_summary: summary_section = f""" <h3 style="color:#1a73e8;margin:24px 0 12px;">📝 会议纪要摘要</h3> <div style="background:#f8f9fa;padding:16px;border-radius:4px;font-size:13px; white-space:pre-line;line-height:1.6;">{minutes_content_summary}</div>""" ``` ```python quote_str = ( f'<blockquote style="border-left:3px solid #ccc;margin:8px 0 0;' f'padding:6px 12px;color:#666;font-size:12px;">{quote}</blockquote>' ) if quote else "" ``` ```python content_preview = confirmed_issue_content[:3000] if len(confirmed_issue_content) > 3000: content_preview += "\n\n...(内容过长,已截断,请到 Gitea 查看完整版)" return f"""<!DOCTYPE html> ... <div style="background:#f8f9fa;padding:16px;border-radius:4px;font-size:13px; white-space:pre-line;line-height:1.7;border:1px solid #e0e0e0;"> {content_preview} </div> ``` ### Technical Analysis Task text, quotes, meeting summaries, issue URLs, and confirmed issue content are interpolated directly into HTML without context-appropriate escaping or sanitization. An attacker who controls repository meeting content can inject arbitrary markup, including deceptive links, images that cause remote tracking requests, or malformed tags that alter the visible message. Most modern email clients restrict scripts, so arbitrary JavaScript exec ...[truncated 1075 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Escape every untrusted text value with `html.escape(..., quote=True)` before interpolation. - Apply context-specific escaping separately for HTML text, attribute values, and URLs. - Validate all URLs with a parser and allowlist expected schemes and Gitea hosts. - Reject `javascript:`, `data:`, protocol-relative, and unexpected external URLs. - If limited markup is required, sanitize it with a maintained allowlist-based HTML sanitizer. - Disable externally loaded images and other remote resources in generated templates. - Add security tests using closing tags, quoted attributes, deceptive links, and malformed HTML payloads. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (45)

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_DIR="$HOME/.config/skill-d-create-issues"
ENV_FILE="$CONFIG_DIR/.env"

echo "🚀 设置 Skill-D (create_issues)..."
echo ""
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs operators to expose an HTTP webhook listener on a public IP and start it as a background service, but provides no authentication, source validation, transport security, or warning about the risks of opening a network-accessible endpoint. In this context, an unauthenticated or weakly protected webhook can be abused to trigger workflows, spam the agent, or manipulate issue-creation behavior via forged push events.

Session Persistence

Medium
Category
Rogue Agent
Content
**启动 Webhook 监听服务(后台常驻):**

```bash
nohup python3 scripts/webhook.py > ~/.config/skill-d-create-issues/webhook.log 2>&1 &
```

### 方式 B:OpenClaw 对话
Confidence
84% confidence
Finding
Running the webhook with nohup as a detached background process creates persistent network-facing behavior outside the user's immediate awareness and normal session lifecycle. In combination with the public webhook setup, this increases the chance that an exposed service remains running indefinitely without supervision, patching, access controls, or restart policy hardening.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The manifest description is written entirely in Chinese and describes the skill behavior in a way that implies a Chinese-language workflow ('正式纪要邮件' and task notifications) without offering any language or locale choice. Under the stated policy, forcing a specific language or locale without opt-in is a natural-language policy violation unless clearly justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The natural-language comments and usage descriptions are presented in Chinese only, including command explanations and operational guidance. This imposes a specific language/locale on users without any visible opt-in, fallback, or justification that the skill is intended only for a Chinese-speaking environment.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The wrapper invokes external Python scripts while passing the full parent environment through unchanged via `env: process.env`. In an automation/agent context, environment variables commonly contain API tokens, credentials, and internal configuration, so any called script gains broad access to secrets beyond what is minimally required for issue creation and email workflow tasks.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The script collects repository members' and organizer email addresses via API calls and emits them in its JSON output, even though its stated purpose is only to validate meeting prerequisites and return issue/minutes content. This creates unnecessary exposure of personal contact data to any downstream consumer of the script output, increasing privacy and data-handling risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script emits attendees' and organizer email addresses in plain JSON without any warning, consent flow, or indication that personally identifiable information will be disclosed. In an agent/automation context, this makes silent bulk collection and propagation of user contact data more dangerous because outputs may be logged, stored, or forwarded automatically.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The module docstring, usage text, argument descriptions, and runtime messages are all written in Chinese, which imposes a specific language on users. Under the policy, locale or language constraints should be opt-in or clearly justified as region-specific; this file provides neither.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module description and all generated email templates are written in Chinese, and the HTML explicitly sets lang="zh" in each template. This imposes a specific language/locale without any visible opt-in or fallback, which matches the natural-language locale policy violation criteria.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script changes and commits `meta.yaml` back to the repository by setting status fields and calling `update_file_in_repo`, but there is no confirmation prompt and no explicit warning near the operation that it will write to remote repository state. Although the module docstring mentions writing `created_issues`, the safety-critical repository update itself is not clearly disclosed at the point of execution.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The script performs a Gitea user email lookup for each assignee using a bot token, which expands the skill's effective scope from updating meeting metadata and generating email payloads into directory/identity data access. This is risky because it enables collection of users' email addresses without clear user consent or strict minimization, and the returned addresses are then used for outbound communications.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This function transmits runtime log entries over the network and writes them into a remote repository using an authorization token, but there is no visible consent, notice, validation of destination, or restriction on what fields may be logged. If entries contain sensitive runtime data, secrets, prompts, or user content, this creates a real exfiltration and privacy risk, especially because all exceptions are silently suppressed and failed or unexpected logging behavior may go unnoticed.

Session Persistence

Medium
Category
Rogue Agent
Content
检测到 confirmed_issue.md 新增时,打印触发信号供 OpenClaw 识别。

启动方式(后台常驻):
    nohup python3 scripts/webhook.py \
      > ~/.config/skill-d-create-issues/webhook.log 2>&1 &

Gitea 每个受管仓库 Settings → Webhooks → Add Webhook:
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
检测到 confirmed_issue.md 新增时,打印触发信号供 OpenClaw 识别。

启动方式(后台常驻):
    nohup python3 scripts/webhook.py \
      > ~/.config/skill-d-create-issues/webhook.log 2>&1 &

Gitea 每个受管仓库 Settings → Webhooks → Add Webhook:
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script's user-facing prompts and setup instructions are entirely in Chinese, including installation status, configuration guidance, and webhook setup details. This imposes a specific language on users without opt-in or any documented locale justification, matching the policy's language/locale violation criterion.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if [ ! -f "$ENV_FILE" ]; then
    cp "$SKILL_DIR/env-example.txt" "$ENV_FILE"
    chmod 600 "$ENV_FILE"
    echo ""
    echo "📝 已创建配置文件:$ENV_FILE"
    echo "请编辑该文件,至少填入:"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This plain-text env example includes operational explanations in Chinese on L05, L08, and L11, which imposes a specific language for understanding important configuration details. There is no indication that the skill is region-specific or that users can choose an English-only alternative, so this is a natural-language policy concern.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
main.js:37