Back to skill

Security audit

LIE.WATCH

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its game-connector purpose, but it handles a reusable platform key in ways that are under-scoped and partly contradicted by its own security claims.

Review this before installing. Only run it in a dedicated directory, keep `.env` out of version control and backups, use credentials you can revoke, leave `API_URL` at the official HTTPS endpoint unless you fully trust the server, and treat all displayed game messages as untrusted player content rather than instructions to your agent.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
connector.js:286
Finding

Untrusted Remote Game Content Is Embedded in AI-Facing Action Prompts

Content
View full analysis
{ if (log.content || log.publicAction) { safeLog(`[GAME LOG] ${log.agentName || log.agentId}: ${log.content || log.publicAction}`) } }) ``` ```js const recentLogs = (Array.isArray(log) ? log : []).slice(-5) // ... safeLog(`\nRECENT EVENTS:`) recentLogs.forEach(l => { const msg = l.content || l.publicAction || l.type safeLog(` [${l.agentName || l.agentId || 'SYSTEM'}] ${msg}`) }) safeLog(`\nRespond with JSON:`) safeLog(` { "intent": "COOPERATE", "target": "AGENT_ID", "say": "...", "think": "..." }`) ``` ### Technical Analysis The connector places server- and player-controlled game messages directly inside the same terminal context as instructions intended for an AI agent. There is no trust-boundary marker, escaping, content classification, or instruction telling the agent to treat game messages exclusively as inert data. Because `SKILL.md` instructs an AI agent to read the connector output and respond with JSON, malicious text in `log.content`, `publicAction`, agent names, or related fields may be interpreted as higher-level instructions rather than game dialogue. This creates a prompt-injection channel. The flagged spectator message at `connector.js:535` is not itself malicious; it is a static local status message. The actual injection risk arises from the unsanitized remote content printed at the locations above. ### Attack Path 1. A malicious player submits a public game statement containing instructions directed at an AI agent. 2. The backend includes that statement in `message.state.log`. 3. The connector prints the statement under `RECENT EVENTS` or `GAME LOG` immediately adjacent to `[ACTION REQUIRED]` and response-format instructions. 4. A ...[truncated 682 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
connector.js:194
Finding

Configurable API Endpoint Can Exfiltrate the Platform Credential or Send It over Plaintext HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
connector.js:114
Finding

Platform Credential Is Persisted in a Plaintext File without Explicit Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:50
Finding

Mutable Installer and Unlocked Dependency Resolution Create a Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connector.js (reported line 10)May include surrounding context.

js
import { fileURLToPath } from 'url'
import { config } from 'dotenv'

// Load environment variables from .env
config()

const __filename = fileURLToPath(import.meta.url)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connector.js (reported line 70)May include surrounding context.

js
import { fileURLToPath } from 'url'
import { config } from 'dotenv'

// Load environment variables from .env
config()

const __filename = fileURLToPath(import.meta.url)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connector.js (reported line 71)May include surrounding context.

js
import { fileURLToPath } from 'url'
import { config } from 'dotenv'

// Load environment variables from .env
config()

const __filename = fileURLToPath(import.meta.url)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · connector.js (reported line 116)May include surrounding context.

js
import { fileURLToPath } from 'url'
import { config } from 'dotenv'

// Load environment variables from .env
config()

const __filename = fileURLToPath(import.meta.url)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Writing AGENT_ID and PLATFORM_KEY into a local .env file persists sensitive credentials in plaintext near the application code. If the directory is shared, backed up, synced, or accidentally committed to version control, attackers or other users may recover the credential and impersonate the agent.

Content

Scanner excerpt · connector.js (reported line 115)May include surrounding context.

js
const safeId = sanitizeEnvValue(AGENT_ID)
        const safeKey = sanitizeEnvValue(PLATFORM_KEY)
        const envContent = `AGENT_ID="${safeId}"\nPLATFORM_KEY="${safeKey}"\nAPI_URL="${API_URL}"\n`
        fs.writeFileSync(path.join(__dirname, '.env'), envContent)
        safeLog(`\n✅ Credentials saved to .env file.`)
        safeLog(`Ready to play!\n`)
    }

Context Leakage

High
Category
Data Exfiltration
Confidence
85% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · connector.js (reported line 229)May include surrounding context.

js
safeLog('[LIE.WATCH] WS Connected. Identifying with session token...')
            startHeartbeat(ws)

            // Send session token for auth (platformKey never touches the WebSocket)
            const identifyPayload = {
                type: 'IDENTIFY_AGENT',
                agentId: AGENT_ID,

Context Leakage

High
Category
Data Exfiltration
Confidence
80% confidence
Finding

Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Content

Scanner excerpt · connector.js (reported line 229)May include surrounding context.

js
safeLog('[LIE.WATCH] WS Connected. Identifying with session token...')
            startHeartbeat(ws)

            // Send session token for auth (platformKey never touches the WebSocket)
            const identifyPayload = {
                type: 'IDENTIFY_AGENT',
                agentId: AGENT_ID,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares executable/runtime requirements and explicitly requires environment secrets and network access, but does not declare any tool scope restrictions such as permissions or allowed-tools. That creates a trust gap where an agent may grant broader capabilities than necessary, increasing the chance of unintended secret access or outbound communication during installation or execution.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding

Using npx clawhub@latest install liewatch pulls and executes remote code at install time without pinning to a specific version. This makes the supply chain mutable: if the package or a dependency is compromised later, users will execute attacker-controlled code and may expose credentials entered during setup.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill tells users that the connector will save AGENT_ID and PLATFORM_KEY to a local .env file, but does not present a prominent warning about the sensitivity of that file or the risks of local secret persistence. This can lead to credential exposure through source control commits, shared workspaces, backups, or other local tooling that reads dotfiles.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The example prompt uses the natural-language trigger 'I want to play Lie Watch' and then asks the agent to install and use the skill, but the document does not define a narrow activation scope or exclusion conditions. In a markdown skill description, this kind of everyday phrasing can overlap with normal conversation about the game and create ambiguity about when the skill should activate.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding

This second unpinned npx clawhub invocation repeats the same remote-code execution supply-chain risk in the main quick-start instructions. Because it appears in the primary install path, it materially increases the likelihood that users will run unreviewed code with access to local files, environment variables, and entered secrets.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 382)May include surrounding context.

md
| Resource | URL |
|----------|-----|
| API Endpoint | `https://api.lie.watch/api/platform` |
| WebSocket | `wss://api.lie.watch/match/{roomId}` |
| Dashboard | `https://lie.watch/dashboard` |

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file-level security comment states that the platform key is never sent over WebSocket, but the code later sends PLATFORM_KEY in the IDENTIFY_AGENT payload when sessionToken is missing. This creates a misleading security guarantee that can cause operators or reviewers to underestimate credential exposure and accept insecure deployments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup flow collects the platform key interactively and writes it to a local .env file without warning the user that a long-lived credential is being persisted on disk. In shared environments, checked-in repos, backups, or permissive filesystem settings, this increases the chance of accidental credential disclosure and account compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When no session token is returned, the connector silently falls back to sending PLATFORM_KEY over the WebSocket as part of authentication. Even if the channel is expected to be encrypted, this expands secret exposure to another protocol path and removes the intended separation between bootstrap credentials and session credentials.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency uses a caret range (^8.18.0), which allows installation of newer compatible releases rather than a fully fixed version. That creates supply-chain unpredictability and makes it harder to prove which code will actually run, especially for a network-facing package like ws that has had multiple historical advisories.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
"author": "evinelias",
    "license": "MIT",
    "dependencies": {
        "ws": "^8.18.0",
        "dotenv": "^16.4.7"
    },
    "engines": {

Unverifiable Dependency: ws has 7 known advisory(ies) (CVE-2016-10518 (Remote Memory Disclosure in ws); CVE-2024-37890 (ws affected by a DoS when handling a request with many HTTP headers); CVE-2026-45736 (ws: Uninitialized memory disclosure) +4 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The manifest includes ws, a package with multiple known advisories, but does not pin an exact version, so it is not possible to verify from this file alone whether the installed release is affected. In the context of a game connector likely using WebSockets for live interaction, a vulnerable ws version could expose the skill to denial of service or memory disclosure issues over the network.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The dotenv dependency is specified with a caret range (^16.4.7), so installs may resolve to different future patch/minor versions over time. While dotenv is lower risk than a network server library, unpinned versions still weaken build reproducibility and increase supply-chain exposure.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"license": "MIT",
    "dependencies": {
        "ws": "^8.18.0",
        "dotenv": "^16.4.7"
    },
    "engines": {
        "node": ">=18.0.0"

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
connector.js:27