Back to skill

Security audit

滴滴出行优惠券自动领取

Security checks for vulnerabilities and agentic risk

Overview

This skill is transparently aimed at claiming Didi coupons, but it uses broad browser control and recurring automation in ways users should review before installing.

Install only if you are comfortable letting the skill use your logged-in Didi browser session, claim coupons automatically, keep daily claim logs, and optionally run on a daily schedule. Review or change the trigger phrases, avoid running it with unrelated browser tabs open, and prefer a package-local locked ws dependency before routine use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T08 · Insecure Dependencies

Warning
Location
scripts/claim.mjs:18
Finding

Unpinned dependency loaded from outside the audited skill directory

Content
View full analysis
import('ws')); ``` ### Technical Analysis The script dynamically imports the `ws` module from a workspace-level `node_modules` directory outside the audited skill package. If that import fails, it falls back to normal Node.js package resolution: ```js await import(wsPath).catch(() => import('ws')); ``` The project contains no package manifest or lockfile that specifies an audited `ws` version and package integrity. Consequently, the effective executable dependency depends on the surrounding workspace, global package-resolution configuration, or package version installed by the operator. Because an imported Node.js module executes with the privileges of the skill process, replacing or poisoning the resolved module creates a code-execution path. This finding does not establish that the currently installed `ws` package is malicious; it identifies an unsafe and unauditable dependency boundary. ### Attack Path 1. An attacker gains the ability to modify the workspace-level `node_modules/ws` package, influence Node.js package resolution, or supply a compromised package during dependency installation. 2. The user invokes the coupon-claiming skill. 3. The script resolves `../../../node_modules/ws/wrapper.mjs`, or falls back to an uncontrolled `ws` package. 4. Node.js loads and executes the dependency before the skill connects to the browser. 5. Malicious module initialization code executes with the same filesystem, network, environment, and process privileges as the skill. ### Impact Assessment Successful exploitation permits arbitrary JavaScript execution under the account running OpenClaw. Dep ...[truncated 379 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/claim.mjs:29
Finding

Arbitrary existing browser tab selected and controlled through CDP

Content
View full analysis
t.type === 'page' && t.url?.includes('didi.cn') && !t.url?.includes('devtools')) || targets.find(t => t.type === 'page' && !t.url?.includes('devtools')); } ``` The selected target is subsequently connected to through its debugging URL: ```js const { ws, send } = await cdpClient(target.webSocketDebuggerUrl); ``` If the selected page is not already a Didi page, the script navigates that existing target to the coupon URL: ```js await send('Page.navigate', { url: COUPON_URL }); await DELAY(3500); ``` ### Technical Analysis When no matching Didi page exists, `getBrowserTarget()` falls back to the first non-DevTools page. It does not verify that the fallback tab was created for this skill, belongs to a dedicated profile, or is safe to replace. The script then establishes a Chrome DevTools Protocol connection to that page. CDP provides powerful control over the selected target, including navigation, JavaScript evaluation, and network-response access. The current implementation uses those capabilities to replace the unrelated page with the coupon page and later evaluates JavaScript in it. This exceeds the minimum authority required for coupon claiming. The skill should create and manage its own browser target rather than take control of an arbitrary existing tab. The reviewed code does not deliberately extract information from the unrelated page, but its selection and navigation behavior can disrupt sensitive or authenticated browsing state. ### Attack Path 1. The user has an OpenClaw browser session with one or more unrelated pages open but no page whose URL contains `di ...[truncated 1137 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (4)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrase "打车有优惠券吗" is a broad, conversational expression that overlaps with ordinary user queries, so the skill may run when the user is merely asking for information rather than consenting to browser automation. In this skill, accidental activation is more concerning because execution launches a browser-connected Node script that can use retained login cookies to claim coupons and schedule recurring automation.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/claim.mjs (reported line 26)May include surrounding context.

js
// ─── CDP 连接 ──────────────────────────────────────────────────────────────────
async function getBrowserTarget() {
  const res = await fetch('http://127.0.0.1:18800/json');
  const targets = await res.json();
  return targets.find(t => t.type === 'page' && t.url?.includes('didi.cn') && !t.url?.includes('devtools'))
      || targets.find(t => t.type === 'page' && !t.url?.includes('devtools'));

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

L108 将定时任务时区固定为“Asia/Shanghai”,但文档没有说明这是仅面向该地区用户的区域性技能,也未提供用户选择其他时区的方式。按自然语言策略,这属于默认施加特定 locale 设置而缺少用户 opt-in。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script explicitly formats the timestamp using toLocaleString('zh-CN'), which hard-codes a specific locale in user-facing output. This is a natural-language/locale policy concern because the file does not offer a user opt-in or explain why Chinese output is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.