Back to skill

Security audit

Wyze Lock

Security checks for vulnerabilities and agentic risk

Overview

This skill openly controls a Wyze smart lock, but its unlock command is not safely enforced at the command boundary.

Install only if you are comfortable giving the skill credentials that can control your Wyze lock. Treat unlock requests as high-risk: require a specific lock name, confirm out of band for shared or untrusted conversations, and consider pinning dependencies or adding a CLI-level confirmation guard before use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/lock:78
Finding

Unlock Operation Does Not Require an Explicit Device Name or Confirmation

Content
View full analysis
(d.nickname || '').trim()).join(', ')); } const s = query.toLowerCase().trim(); const hits = list.filter(d => (d.nickname || '').toLowerCase().includes(s)); if (!hits.length) die('no lock matching "' + query + '". Try: status'); if (hits.length > 1) die('"' + query + '" matches ' + hits.length + ' locks: ' + hits.map(d => (d.nickname || '').trim()).join(', ')); return hits[0]; } ``` ```javascript if (cmd === 'lock' || cmd === 'unlock') { const lock = await pick(rest[0]); const name = (lock.nickname || '').trim(); if (cmd === 'lock') await w.lockDoor(lock); else await w.unlockDoor(lock); } ``` ### Technical Analysis The `unlock` command passes `rest[0]` to `pick()` without verifying that the caller supplied a non-empty lock name. When the associated Wyze account contains exactly one lock, `pick()` automatically returns that lock if the query is absent. Consequently, the following command can trigger an unlock operation without naming the target: ```bash node scripts/lock unlock ``` The implementation also has no confirmation flag, confirmation token, or other programmatic authorization checkpoint before invoking `unlockDoor()`. This contradicts the documented safety requirement that an unlock request identify a single named lock and receive explicit user confirmation. Although automatic selection may be convenient for read-only status operations, it is unsafe for a security-sensitive operation that changes physical access controls. Safety enforcement is delegated entirely to the calling ...[truncated 1232 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill can access sensitive environment-based secrets such as WYZE_EMAIL, WYZE_KEY_ID, WYZE_API_KEY, and token paths, but it does not declare any tool scope or permission boundaries. In a skill that can physically unlock a door, undocumented env access weakens reviewability and increases the chance that secrets are exposed or misused by the runtime or future changes without explicit user awareness.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a caret range (^2.12.2), which permits automatic installation of newer 2.x releases. This creates supply-chain risk because future upstream changes or a compromised release could be pulled in without explicit review, and this skill controls a smart lock, making even dependency-level compromise security-relevant.

Content

Scanner excerpt · scripts/package.json (reported line 6)May include surrounding context.

json
"private": true,
  "description": "Runtime dependency for the Wyze lock OpenClaw skill",
  "dependencies": {
    "wyze-node": "^2.12.2"
  }
}

Static analysis

No suspicious patterns detected.