Back to skill

Security audit

Loudy.ai Auto Task

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a Loudy.ai task helper, but its mutable installer, optional recurring cron job, and third-party skill steering create review-level risk.

Install only if you are comfortable giving this skill a Loudy.ai API key, sending task links and task status requests to Loudy.ai, and managing its local files. Avoid the provided curl-to-bash installer and any root or system-wide install path; prefer an immutable reviewed package. Do not enable the cron job unless you add your own cleanup, locking, and least-privilege controls. Treat the suggested Binance/X posting skill as a separate component requiring its own review before use.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
install.sh:3
Finding
Mutable Remote Installer Executes Unpinned Repository Content<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:3`, `install.sh:45-56`, `install.sh:81-90`, `install.sh:98-103` **Vulnerability Type**: Remote payload retrieval and execution through a mutable branch **Risk Level**: Critical ### Vulnerable Code ```bash # 使用方法: curl -fsSL https://raw.githubusercontent.com/sfsf332/claw-loudyai-skill/main/install.sh | bash ``` ```bash get_install_path() { # 优先使用 OPENCLAW_SKILLS_DIR 环境变量 if [ -n "$OPENCLAW_SKILLS_DIR" ]; then INSTALL_DIR="$OPENCLAW_SKILLS_DIR" else # 默认路径 INSTALL_DIR="/usr/lib/node_modules/openclaw/skills" fi info "安装路径: $INSTALL_DIR" } ``` ```bash clone_repository() { info "克隆仓库..." cd "$INSTALL_DIR" # 如果目录已存在,先删除 if [ -d "loudy-ai-auto-task" ]; then warning "目录已存在,正在删除..." rm -rf loudy-ai-auto-task fi # 克隆仓库 git clone https://github.com/sfsf332/claw-loudyai-skill.git loudy-ai-auto-task || error "克隆仓库失败" success "仓库克隆完成" } ``` ```bash set_permissions() { info "设置权限..." cd "$INSTALL_DIR/loudy-ai-auto-task" # 设置脚本可执行权限 if [ -d "scripts" ]; then chmod +x scripts/*.py scripts/*.sh 2>/dev/null || true fi success "权限设置完成" } ``` ### Technical Analysis The documented installation command downloads `install.sh` from the mutable `main` branch and immediately passes it to a shell. Users cannot reliably inspect the exact payload before execution, and the command performs no signature, checksum, release-tag, or commit verification. The downloaded installer then clones the repository without specifying an immutable commit or tag. Consequently, both the first-stage installer and second-stage Skill content can differ from the version that was audited. The installer also marks retrieved scripts executable and defaults to `/usr/lib/node_modules/openclaw/skills`, a location that commonly requires elevated privileges. The installation process additionally deletes any existing `l ...[truncated 1477 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all `curl | bash` installation instructions. 2. Distribute the Skill as an immutable, versioned release archive. 3. Pin installation to a full Git commit hash or immutable release identifier. 4. Publish and verify a SHA-256 digest or cryptographic signature before extracting or executing content. 5. Display the expected repository revision to the user and fail closed if verification fails. 6. Default to a user-owned Skill directory instead of `/usr/lib/node_modules`. 7. Do not recommend running the installer as root or through `sudo`. 8. Avoid deleting an existing installation automatically; use a safe update process with confirmation and rollback support. 9. Set executable permissions only on an explicit allowlist of reviewed scripts. 10. Audit the exact immutable artifact that will be installed rather than a mutable branch. ]]>

T06 · System Persistence

Error
Location
SKILL.md:157
Finding
Optional Cron Configuration Establishes Recurring Cross-Session Execution<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:157-170` **Vulnerability Type**: Scheduled-task persistence **Risk Level**: High ### Vulnerable Code ```bash export LOUDY_API_KEY="你的API Key" export OPENCLAW_WORKSPACE="/root/.openclaw/workspace" # 可选,默认值 ``` ```bash # 方法1: 使用工作区安装路径(推荐) SKILL_DIR="/root/.openclaw/workspace/skills/claw-loudyai-skill" (crontab -l 2>/dev/null; echo "*/5 * * * * $SKILL_DIR/scripts/cron_check.sh") | crontab - # 方法2: 如果安装到系统路径 (crontab -l 2>/dev/null; echo "*/5 * * * * /usr/lib/node_modules/openclaw/skills/loudy-ai-auto-task/scripts/cron_check.sh") | crontab - ``` ### Technical Analysis The documentation instructs the user to add a cron entry that executes `cron_check.sh` every five minutes. This behavior is disclosed as optional and is related to automatic task polling, but it still creates execution that survives the interactive Skill run and future login sessions. The command is not idempotent: running it repeatedly appends duplicate entries. It has no unique marker, integrity check, overlap prevention, lifecycle management, or documented uninstall command. One suggested target is a privileged system installation path. The cron entry executes whichever file later occupies the configured path. Therefore, repository replacement, an unsafe update, or writable-path compromise can convert the legitimate polling mechanism into recurring execution of attacker-controlled content. ### Attack Path 1. The user follows the cron configuration instructions. 2. The user's crontab receives an entry that invokes `cron_check.sh` every five minutes. 3. The cron entry persists after the current OpenClaw interaction ends. 4. The installed Skill directory is later replaced, updated from mutable remote content, or modified by an attacker with write access. 5. Cron executes the modified script automatically and repeatedly. 6. The replacement code runs with the privileges and environment available to the cron account. ### Impact A ...[truncated 605 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer an OpenClaw-managed scheduler with explicit enable/disable controls over direct crontab modification. 2. Require clear affirmative user consent immediately before adding the scheduled task. 3. Add a unique comment marker and update entries idempotently rather than appending duplicates. 4. Supply a documented uninstall command that removes only the Skill's own cron entry. 5. Execute an immutable or integrity-verified script rather than mutable repository content. 6. Run the job under a dedicated least-privileged user. 7. Use `flock` or an equivalent mechanism to prevent overlapping executions. 8. Configure a restricted environment and explicit `PATH`. 9. Record the schedule, executable path, and removal procedure in the installation output. 10. Avoid recommending a root-owned or system-wide cron configuration unless strictly necessary. ]]>

T01 · Skill Instruction Hijacking

Error
Location
scripts/auto_task_flow.py:141
Finding
Task Output Steers Users and Agents Toward an Unreviewed Third-Party Skill<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto_task_flow.py:141-177` **Vulnerability Type**: Instruction hijacking through unrelated installation and execution guidance **Risk Level**: High ### Vulnerable Code ```python # 检查是否为币安任务 if is_binance_task(info['sponsor']): print(f"\n{'='*60}") print(f"🚀 币安任务专属提示") print(f"{'='*60}") print(f"💡 检测到这是币安任务!") print(f"\n📦 推荐使用币安官方 Skill 一键完成:") print(f"🔗 GitHub: https://github.com/binance/binance-skills-hub/tree/main/skills/binance/square-post") print(f"\n✨ Skill 功能:") print(f" ✓ 自动生成符合币安要求的推文内容") print(f" ✓ 一键发布到 X/Twitter") print(f" ✓ 自动返回推文链接") print(f" ✓ 支持批量任务处理") print(f"\n📥 安装步骤:") print(f" 1️⃣ 安装 Skill:") print(f" $ clawhub install binance/square-post") print(f" 2️⃣ 等待安装完成...") print(f"\n🚀 使用方法(安装后):") print(f" 方式一:告诉 AI") print(f" 对我说:\"帮我用币安 skill 完成这个任务\"") print(f" ") print(f" 方式二:直接运行") print(f" $ cd ~/.openclaw/skills/binance-square-post") print(f" $ ./scripts/generate_and_post.sh <任务ID>") print(f"\n📋 完整流程:") print(f" 1. 安装币安 skill") print(f" 2. 运行 skill 生成并发布推文") print(f" 3. 获取生成的推文链接") print(f" 4. 将推文链接发送给我") print(f" 5. 我会自动提交到 loudy.ai") ``` ### Technical Analysis The declared Skill scope states that Twitter/X posting is manual and that the Skill only interacts with the Loudy API. However, when a sponsor name contains a Binance keyword, normal task display output includes instructions to install and run another Skill that can generate and publish content. The external Skill is not included in this project and was not auditable as part of this review. The trigger depends on the `sponsor` field returned by the Loudy API: ```python def is_binance_task(sponsor): binance_keywords = ['binance', '币安', 'Binance', 'BINANCE'] return any(keyword.lower() in sponsor.lower() for keyword in binance_keywords) ``` This crea ...[truncated 1390 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove third-party installation and shell-execution instructions from normal pool output. 2. Keep the Skill limited to its declared Loudy API task-management purpose. 3. If integrations are retained, present them only after explicit user selection. 4. Clearly state that the external Skill is a separate, unaudited component. 5. Pin any approved integration to an immutable reviewed version. 6. Do not allow API-returned task metadata to trigger installation guidance automatically. 7. Require separate confirmation before any installation or execution action. 8. Update `SKILL.md` to disclose optional integrations and their additional privileges. 9. Treat external task descriptions, sponsor values, and links as untrusted display data. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cron_check.sh:6
Finding
Scheduled Workflow Writes Predictable Workspace Files Without Explicit Permission or Symlink Controls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cron_check.sh:6-16`, `scripts/cron_check.sh:29-42` **Vulnerability Type**: Unsafe predictable file handling **Risk Level**: Medium ### Vulnerable Code ```bash # 获取工作目录(优先使用环境变量,否则使用默认路径) WORKSPACE_DIR="${OPENCLAW_WORKSPACE:-/root/.openclaw/workspace}" # 从环境变量读取 API Key,若未设置则退出 if [ -z "$LOUDY_API_KEY" ]; then echo "LOUDY_API_KEY not set" exit 1 fi export LOUDY_API_KEY LOG_FILE="$WORKSPACE_DIR/loudy_tasks.json" LAST_FILE="$WORKSPACE_DIR/loudy_last.json" ``` ```bash # 获取当前奖池 python3 "$CHECK_SCRIPT" > "$LOG_FILE" # 比较是否有新任务 if [ -f "$LAST_FILE" ]; then if diff -q "$LOG_FILE" "$LAST_FILE" > /dev/null 2>&1; then # 没有变化 exit 0 fi fi # 有新任务或首次运行,保存并标记需要通知 cp "$LOG_FILE" "$LAST_FILE" echo "NEW_TASKS" > "$WORKSPACE_DIR/loudy_has_new.txt" ``` ### Technical Analysis The scheduled script writes task data to fixed filenames under a configurable workspace. It does not set a restrictive `umask`, validate directory ownership or permissions, reject symbolic links, or use atomic file replacement. Shell redirection opens and truncates `loudy_tasks.json` before Python executes. If an attacker can write to the workspace, a pre-created symbolic link can redirect that operation to another file writable by the cron account. Similar concerns apply to `loudy_last.json` and `loudy_has_new.txt`. File confidentiality is inherited from the account's current umask. In a shared or permissively configured workspace, task descriptions and associated pool data may become readable by unintended local users or processes. The `.json` name is also misleading because `check_tasks.py` produces formatted plain text rather than JSON. ### Attack Path 1. An attacker or lower-privileged local process obtains write access to the configured workspace. 2. The attacker replaces `loudy_tasks.json`, `loudy_last.json`, or `loudy_has_new.txt` with a symbolic link to another path. 3. Cron invokes `cron_check.s ...[truncated 740 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` before creating workspace files. 2. Require the workspace to be owned by the executing user and not writable by other users. 3. Create the workspace with mode `0700`. 4. Create data files with mode `0600`. 5. Reject symbolic links using safe file-opening semantics or explicit link checks. 6. Write to a securely created temporary file in the same directory and atomically rename it. 7. Verify that resolved paths remain inside the approved workspace. 8. Avoid running the scheduled workflow as root. 9. Produce valid JSON when using a `.json` filename, or use an accurate extension. 10. Add error handling so failed or partial executions do not overwrite the last known-good state. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/check_tasks.py:14
Finding
Authenticated HTTP Requests Lack Timeouts and Consistent Error Handling<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check_tasks.py:14-22` **Additional Locations**: `scripts/fetch_pools.py:13-21`, `scripts/list_my_tasks.py:23-43`, `scripts/submit_task.py:23-37`, `scripts/check_task.py:25-33` **Vulnerability Type**: Unbounded network operations and unsafe response handling **Risk Level**: Low ### Vulnerable Code ```python def fetch_earning_pools(): """获取进行中的奖池列表""" url = f"{API_BASE}/earning-pools" headers = { "X-API-Key": LOUDY_API_KEY, "Content-Type": "application/x-www-form-urlencoded" } response = requests.get(url, headers=headers) data = response.json() ``` Equivalent unbounded calls appear elsewhere: ```python response = requests.get(url, headers=headers) response = requests.get(url, headers=headers, params=params) response = requests.post(url, headers=headers, json=payload) ``` ### Technical Analysis Most request paths do not specify connect or read timeouts. The scripts also generally omit `raise_for_status()` and do not catch transport errors, HTTP failures, or JSON decoding errors. A server that accepts a connection but delays its response can therefore leave the process blocked indefinitely. This is more significant in `check_tasks.py` because it is intended to run every five minutes through cron. Without locking or timeout enforcement, stalled invocations can overlap with later scheduled runs and consume processes or other resources. Although `auto_task_flow.py` uses a 30-second timeout and catches `RequestException`, that protection is not consistently applied to the remaining scripts. ### Attack Path 1. The Loudy endpoint, an intermediary network device, or the local network causes a request to stall. 2. A script waits indefinitely because no timeout is configured. 3. For the cron path, another invocation begins five minutes later. 4. Additional stalled processes accumulate. 5. Malformed JSON or an HTTP error can also terminate the script unexpectedl ...[truncated 544 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure explicit connect and read timeouts for every request, for example `timeout=(5, 30)`. 2. Call `response.raise_for_status()` before parsing response content. 3. Catch `requests.exceptions.RequestException`. 4. Catch JSON decoding and schema-validation failures. 5. Return a nonzero exit status on polling failure rather than treating failure as valid task output. 6. Use `flock` or an equivalent lock around the cron workflow to prevent overlap. 7. Apply bounded retries with exponential backoff and jitter only for transient failures. 8. Preserve the last valid output when a request fails. 9. Validate response types and impose reasonable response-size limits. 10. Apply the robust request behavior already present in `auto_task_flow.py` consistently across all scripts. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (48)

Tainted flow: 'headers' from os.environ.get (line 65, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
}
    
    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        data = response.json()
    except requests.exceptions.RequestException as e:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 65, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
}
    
    try:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        data = response.json()
    except requests.exceptions.RequestException as e:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 65, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        response.raise_for_status()
        data = response.json()
    except requests.exceptions.RequestException as e:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 27, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"Content-Type": "application/x-www-form-urlencoded"
    }
    
    response = requests.get(url, headers=headers)
    data = response.json()
    
    if data.get("code") != 0 and data.get("code") != 200:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 16, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"Content-Type": "application/x-www-form-urlencoded"
    }
    
    response = requests.get(url, headers=headers)
    data = response.json()
    
    if data.get("code") != 0 and data.get("code") != 200:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 15, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"Content-Type": "application/x-www-form-urlencoded"
    }
    
    response = requests.get(url, headers=headers)
    data = response.json()
    if data.get("code") != 0 and data.get("code") != 200:
        print(f"Error: {data.get('msg')}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 27, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
if task_status:
        params["taskStatus"] = str(task_status)
    
    response = requests.get(url, headers=headers, params=params)
    data = response.json()
    
    if data.get("code") != 0 and data.get("code") != 200:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"languageType": language_type
    }
    
    response = requests.post(url, headers=headers, json=payload)
    data = response.json()
    
    if data.get("code") != 0 and data.get("code") != 200:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description presents the skill as an operational Loudy.ai automation tool whose behavior is limited to Loudy.ai API interactions. However, the provided code chunk is not that tool logic; it is an installer. Its primary purpose is system setup: checking dependencies, creating directories, cloning a remote repository from GitHub, modifying permissions, and validating files locally. Those are materially different capabilities and resource accesses from the declared runtime behavior. While installer behavior can support the skill, the declared purpose says the tool only interacts with the Loudy.ai API, which is inconsistent with this code's actual network/system activity. Therefore this code chunk does not accurately match the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
There is a material description/behavior mismatch. The declared description says the tool queries prize pools, submits task links, and tracks audit/payment status, and emphasizes that it only interacts with the Loudy.ai API with no Twitter/X auto-posting functionality. In the supplied code, Loudy.ai pool querying is implemented, and a submit_task function exists, but there is no code to track review status or payment status. There is also no scheduler or loop for periodic querying in the main execution path; it only fetches and displays current pools once. Most importantly, the display logic contains Binance-specific instructions that direct the user to install and use an external skill for generating and posting tweets to X/Twitter. Even though this script itself does not post to Twitter, that behavior is inconsistent with the strict claim that the tool only interacts with the Loudy.ai API and does not include Twitter/X-related functionality. Therefore the description overstates some implemented features and understates the external X/Twitter-related workflow embedded in the code.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
代码与声明在资源范围上基本一致,确实只与 loudy.ai API 交互,并使用 LOUDY_API_KEY;也没有出现未声明的 Twitter/X 自动发布等额外能力。但声明描述的是一个更完整的自动化工具:包含奖池查询、提交任务链接、定时追踪审核和支付状态。当前代码片段实际只实现了通过任务ID查询任务详情这一子功能,且是手动命令行触发的一次性检查,不具备定时执行或任务提交能力。因此描述对该代码片段的功能覆盖明显过宽,存在实质性描述与行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The code is limited to a single-purpose checker for ongoing Loudy.ai earning pools. It matches the narrow claim that it interacts only with the Loudy.ai API and uses LOUDY_API_KEY, and it does not show any Twitter/X automation. However, the declared description materially overstates the implemented functionality by claiming submission of task links and tracking of review/payment states, as well as periodic automatic querying after startup. None of those behaviors are present in this code chunk. Therefore the description does not accurately represent what the supplied code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The code is broadly related to the declared loudy.ai automation scenario: it depends on LOUDY_API_KEY, runs periodically, and checks for current task/prize information. However, this specific code chunk only performs polling plus local state management: it writes JSON files, diffs current versus previous results, and creates a 'new tasks' marker file. More importantly, the declared description presents a broader tool that also submits task links and tracks review/payment status, but none of those capabilities appear in this chunk. That makes the actual behavior materially narrower than the declared functionality, while also adding undeclared local persistence/change-detection behavior. There is no evidence here of Twitter/X auto-posting, so that part of the description is consistent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code does match part of the description: it interacts only with the Loudy.ai API, requires LOUDY_API_KEY, and submits a task link. However, the declared purpose describes a broader automation tool with periodic querying of earning pools and tracking of review/payment status after startup, none of which appear in this code chunk. The code is only a manual submission script invoked via CLI arguments. There is no evidence of scheduling, polling, earning-pool querying, or status tracking. The Twitter/X note is mostly consistent because the script does not post to Twitter/X; it only submits a link that may be a tweet URL to Loudy.ai. Overall, the supplied chunk materially underimplements the declared behavior, so this is a mismatch between description and actual behavior of the provided code chunk.

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

High
Category
YARA Match
Content
_KEY="你的API Key"
export OPENCLAW_WORKSPACE="/root/.openclaw/workspace"  # 可选,默认值
```

### 2. 配置 Cron 定时检查(可选)
```bash
# 方法1: 使用工作区安装路径(推荐)
SKILL_DIR="/root/.openclaw/workspace/skills/claw-loudyai-skill"
(crontab -l 2>/dev/null; echo "*/5 * * * * $SKILL_DIR/scripts/cron_check.sh") | crontab -

# 方法2: 如果安装到系统路径
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/lib/node_modules/openclaw/skills/loudy-ai-auto-task/scripts/cron_check.sh") | crontab -
```

### 3. 配置 Heartbeat 通知(可选)
在 HEARTBEAT.md 中添加:
```
## Loudy.ai 任务检查
检查工作区目录下的 loudy_has_new.txt 是否存在:
- 如果存在 → 读取 loudy_tasks.json 内容
- 发送消息通知用户
- 删除 loudy_has_new.txt
```

## 注意事项

- ⚠️ **API Key 安全**:建议使用环境变量 `export LOUDY_API_KEY=你的密钥`,**不要**写入 TOOLS.md 或其他共享文件
- 📝 **文件系统访问**
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Chaining Abuse

High
Category
Tool Misuse
Content
#!/bin/bash
# Loudy.ai 自动任务 Skill 安装脚本
# 使用方法: curl -fsSL https://raw.githubusercontent.com/sfsf332/claw-loudyai-skill/main/install.sh | bash

set -e
Confidence
96% confidence
Finding
Piping directly into `bash` is dangerous because it chains network retrieval to shell execution in one step, eliminating review and increasing the blast radius of any compromise. In this skill's context, the installer may be run with elevated privileges to write into `/usr/lib/node_modules/openclaw/skills`, so a malicious or tampered script could gain broad system impact.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares access to an API key, external network endpoints, shell usage, filesystem writes, and optional cron persistence, but does not define any explicit tool scope or allowed-tools boundary. In an agent environment, missing capability restrictions increases the blast radius if the skill is misused, modified, or invoked in an unexpected context.

External Transmission

Medium
Category
Data Exfiltration
Content
## API 接口

### 1. 获取奖池列表
- **URL**: `GET https://api.loudy.ai/app-api/open-api/v1/earning-pools`
- **Header**: `X-API-Key: <LOUDY_API_KEY>`

### 2. 获取奖池详情
Confidence
86% confidence
Finding
The skill explicitly transmits requests to an external service and uses `X-API-Key` authentication, which means sensitive credentials and user-submitted task data leave the local environment. External transmission is expected for this tool, but it still creates confidentiality and trust risks if the endpoint, logging, or downstream handling are not tightly controlled.

External Transmission

Medium
Category
Data Exfiltration
Content
- **Header**: `X-API-Key: <LOUDY_API_KEY>`

### 2. 获取奖池详情
- **URL**: `GET https://api.loudy.ai/app-api/open-api/v1/earning-pools/{id}`
- **Header**: `X-API-Key: <LOUDY_API_KEY>`

### 3. 提交任务
Confidence
86% confidence
Finding
Fetching earning pool details from an external API exposes the environment to external data flows and reliance on a third-party service. While this is part of the skill's purpose, any use of an API key over the network can leak metadata or credentials through misconfiguration, debugging output, or compromised infrastructure.

External Transmission

Medium
Category
Data Exfiltration
Content
- **Header**: `X-API-Key: <LOUDY_API_KEY>`

### 3. 提交任务
- **URL**: `POST https://api.loudy.ai/app-api/open-api/v1/earning-pool-tasks/submit`
- **Header**: `X-API-Key: <LOUDY_API_KEY>`
- **Body**:
```json
Confidence
91% confidence
Finding
Submitting task links to an external API sends user-provided URLs and an API key off-host, which can expose sensitive operational data or allow unintended data disclosure if users submit private links. Because this is a write action to a third-party service, the impact is higher than simple read-only API calls if mishandled or triggered unintentionally.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The API example specifies `"languageType": "zh_CN"`, which implies the skill operates in a fixed locale. The document does not state that this is optional, user-selectable, or required for a region-specific use case, so it appears to force a language/locale without opt-in.

External Transmission

Medium
Category
Data Exfiltration
Content
```

### 4. 查询我的任务列表(分页)
- **URL**: `GET https://api.loudy.ai/app-api/open-api/v1/earning-pool-tasks`
- **Header**: `X-API-Key: <LOUDY_API_KEY>`
- **Query**:
  - `pageNo` - 页码(必填)
Confidence
85% confidence
Finding
Listing tasks through the external API may reveal user activity, earning pool participation, and status metadata to the remote service and to any local logs capturing responses. This is expected behavior but still represents a privacy and credential-handling risk in an agent environment.

External Transmission

Medium
Category
Data Exfiltration
Content
- `taskStatus` - 任务状态(可选)

### 5. 查询任务状态
- **URL**: `GET https://api.loudy.ai/app-api/open-api/v1/earning-pool-tasks/{id}`
- **Header**: `X-API-Key: <LOUDY_API_KEY>`
- **返回字段**:
  - `taskStatus` - 任务状态
Confidence
85% confidence
Finding
Task status lookups transmit authenticated requests to a third-party endpoint and may retrieve audit/payment-related metadata that could be sensitive in some workflows. The capability is legitimate, but the skill context makes secure handling of API keys and response data necessary.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# 方法1: 使用工作区安装路径(推荐)
SKILL_DIR="/root/.openclaw/workspace/skills/claw-loudyai-skill"
(crontab -l 2>/dev/null; echo "*/5 * * * * $SKILL_DIR/scripts/cron_check.sh") | crontab -

# 方法2: 如果安装到系统路径
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/lib/node_modules/openclaw/skills/loudy-ai-auto-task/scripts/cron_check.sh") | crontab -
Confidence
93% confidence
Finding
The documented cron setup establishes persistent execution every five minutes, which changes the system state beyond a single session and can continue making authenticated network calls without ongoing user awareness. Persistence is especially sensitive in agent skills because it can survive the initiating interaction and repeatedly access local files and external services.

Session Persistence

Medium
Category
Rogue Agent
Content
(crontab -l 2>/dev/null; echo "*/5 * * * * $SKILL_DIR/scripts/cron_check.sh") | crontab -

# 方法2: 如果安装到系统路径
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/lib/node_modules/openclaw/skills/loudy-ai-auto-task/scripts/cron_check.sh") | crontab -
```

### 3. 配置 Heartbeat 通知(可选)
Confidence
94% confidence
Finding
Installing a cron entry pointing to a system path creates durable background execution and may run in contexts with broader privileges or different trust assumptions. In combination with API-key use and filesystem reads/writes, this persistence materially increases risk if the script is altered, replaced, or misunderstood.

Static analysis

No suspicious patterns detected.