Back to skill

Security audit

Nest Devices

Security checks for vulnerabilities and agentic risk

Overview

This Nest skill is mostly purpose-aligned, but its always-on public webhook and alert forwarding create review-worthy privacy and security risks.

Review carefully before installing. Use this only if you are comfortable exposing a Nest event webhook through Cloudflare, sending doorbell/person snapshots and activity alerts to Telegram, and running persistent services. Require authenticated Pub/Sub push validation, pin and verify cloudflared, store tokens in restricted secret files or systemd credentials, avoid passing the full environment to subprocesses, and add explicit confirmation or opt-in for camera and third-party alerting paths.

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 (5)

T01 · Skill Instruction Hijacking

Error
Location
scripts/nest-webhook.py:318
Finding

Unauthenticated public webhook permits forged events and Agent message injection

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/nest-webhook.py:323
Finding

Unbounded webhook request body permits remote denial of service

Content
View full analysis
Remediation
View remediation
MAX_BODY_SIZE: self.send_json({'error': 'Request too large'}, 413) return ``` 2. Configure socket and request read timeouts. 3. Authenticate the request before performing expensive event processing. 4. Enforce body-size and request-rate limits at Cloudflare or another reverse proxy. 5. Consider a bounded threaded server or production HTTP server so one slow client cannot block all deliveries. 6. Apply systemd memory, CPU, task, and restart-rate limits to contain resource exhaustion. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:183
Finding

Unpinned and unverified executable is installed as a persistent service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:226
Finding

Clawdbot hook bearer token is stored directly in a systemd unit

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/nest-webhook.py:181
Finding

Camera snapshot temporary files are not reliably deleted

Content
View full analysis
0: with open(output_path, 'rb') as f: data = f.read() os.unlink(output_path) print(f"[RTSP] Captured {len(data)} bytes") return data return None ``` The exception path also returns without cleanup: ```python except Exception as e: print(f"[RTSP] Error: {e}") return None ``` ### Technical Analysis The temporary file is created with `delete=False`, and deletion only occurs after ffmpeg successfully produces a non-empty image and the file is successfully read. The file remains on disk if: - ffmpeg times out or throws an exception. - ffmpeg exits without writing a non-empty image. - Reading the image fails. - Another exception occurs after file creation but before `os.unlink`. - The process terminates during capture or processing. Because these files contain or may partially contain camera imagery, they are more sensitive than ordinary temporary data. ### Attack Path 1. A doorbell or person event causes the primary image-generation path to fail. 2. The service falls back to RTSP frame capture. 3. ffmpeg creates or partially writes the temporary JPEG. 4. Capture times out, produces an empty file, or another exception occurs. 5. The function returns without deleting the file. 6. Repeated failures accumulate residual files in the temporary directory; any user or process with applicable filesystem access may inspect them. The unauthenticated webhook finding can increase exploitabilit ...[truncated 545 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (45)

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 98)May include surrounding context.

python
}).encode()

        req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data, method='POST')
        with urllib.request.urlopen(req, timeout=10) as resp:
            result = json.loads(resp.read())
            _access_token['token'] = result['access_token']
            _access_token['expires'] = time.time() + result.get('expires_in', 3600) - 60

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 126)May include surrounding context.

python
'Content-Type': 'application/json',
        })

        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
            image_url = result.get('results', {}).get('url')
            image_token = result.get('results', {}).get('token')

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 172)May include surrounding context.

python
'Content-Type': 'application/json',
        })

        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
            image_url = result.get('results', {}).get('url')
            image_token = result.get('results', {}).get('token')

Tainted flow: 'img_req' from os.environ.get (line 136, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 139)May include surrounding context.

python
img_req = urllib.request.Request(image_url, headers={
                'Authorization': f'Basic {image_token}',
            })
            with urllib.request.urlopen(img_req, timeout=15) as img_resp:
                image_data = img_resp.read()
                print(f"[IMAGE] Downloaded {len(image_data)} bytes")
                return image_data

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
98% confidence
Finding

The code transmits camera snapshots and event captions to Telegram automatically, which is a third-party external service unrelated to core Nest device control. In the context of a smart-home skill, this materially increases privacy risk because images of visitors or occupants can be disclosed off-platform without user confirmation or clear consent controls.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 238)May include surrounding context.

python
'Content-Type': f'multipart/form-data; boundary={boundary}',
        })

        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
            if result.get('ok'):
                print(f"[TELEGRAM] Photo sent successfully")

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

Event alerts are sent to Telegram based on environment-configured bot credentials and chat ID, creating an external disclosure path for occupancy/security events. Even without images, doorbell/person alerts reveal presence patterns and home activity to a third party.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 268)May include surrounding context.

python
'Content-Type': 'application/json',
        })

        with urllib.request.urlopen(req, timeout=10) as resp:
            return json.loads(resp.read()).get('ok', False)
    except Exception as e:
        print(f"[TELEGRAM] Error: {e}")

Tainted flow: 'req' from os.environ.get (line 287, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The webhook forwards event metadata to a gateway URL fully controlled by the CLAWDBOT_GATEWAY_URL environment variable, with no allowlist or origin restriction. If that variable is misconfigured or attacker-controlled, sensitive occupancy/event data and the bearer hook token can be sent to an arbitrary server, enabling exfiltration and token abuse.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 295)May include surrounding context.

python
'Content-Type': 'application/json',
            },
        )
        urllib.request.urlopen(req, timeout=5)
    except Exception as e:
        print(f"[HOOK] Error: {e}")

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented behavior includes undisclosed credential retrieval from 1Password and device enumeration while omitting or overstating features like temperature scheduling and direct doorbell handling. Security-relevant behavior hidden behind an inaccurate description undermines informed approval and can expose secrets or device metadata under the guise of ordinary home automation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented behavior includes undisclosed credential retrieval from 1Password and device enumeration while omitting or overstating features like temperature scheduling and direct doorbell handling. Security-relevant behavior hidden behind an inaccurate description undermines informed approval and can expose secrets or device metadata under the guise of ordinary home automation.

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

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

md
---
name: nest-devices
description: Control Nest smart home devices (thermostat, cameras, doorbell) via the Device Access API. Use when asked to check or adjust home temperature, view camera feeds, check who's at the door, monitor rooms, or set up temperature schedules.
metadata:
  clawdbot:
    emoji: "🏠"
---

# Nest Device Access

Control Nest devices via Google's Smart Device Management API.

## Setup

### 1. Google Cloud & Device Access

1. Create a Google Cloud project at [console.cloud.google.com](https://console.cloud.google.com)
2. Pay the $5 fee and create a Device Access project at [console.nest.google.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 31)May include surrounding context.

python
# 1Password token for Nest API credentials
OP_TOKEN = os.environ.get('OP_SVC_ACCT_TOKEN', '')

# Cache for Nest credentials and access token
_nest_creds = {}
_access_token = {'token': None, 'expires': 0}

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 79)May include surrounding context.

python
# 1Password token for Nest API credentials
OP_TOKEN = os.environ.get('OP_SVC_ACCT_TOKEN', '')

# Cache for Nest credentials and access token
_nest_creds = {}
_access_token = {'token': None, 'expires': 0}

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/nest.py (reported line 82)May include surrounding context.

python
# 1Password token for Nest API credentials
OP_TOKEN = os.environ.get('OP_SVC_ACCT_TOKEN', '')

# Cache for Nest credentials and access token
_nest_creds = {}
_access_token = {'token': None, 'expires': 0}

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
89% confidence
Finding

The code clones the full process environment and passes it to the 1Password CLI, which broadens exposure of unrelated secrets to a child process unnecessarily. If the child process, its plugins, or diagnostics are compromised, environment-resident credentials beyond the intended service-account token may leak.

Content

Scanner excerpt · scripts/nest-webhook.py (reported line 54)May include surrounding context.

python
print("[NEST] No OP_SVC_ACCT_TOKEN set")
        return None

    env = {**os.environ, 'OP_SERVICE_ACCOUNT_TOKEN': OP_TOKEN}
    op = os.path.expanduser('~/.local/bin/op')
    vault_id = 'Alfred'  # Use vault name

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/nest.py (reported line 32)May include surrounding context.

python
"""
    # Try 1Password first
    op_token = None
    for key in os.environ:
        if key.startswith('OP_TOKEN_') or key == 'OP_SERVICE_ACCOUNT_TOKEN':
            op_token = os.environ[key]
            break

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
92% confidence
Finding

Passing the entire parent environment into the op subprocess unnecessarily exposes all ambient secrets and runtime context to an external binary. If the op binary is compromised, replaced via PATH ambiguity, or behaves unexpectedly, unrelated credentials in the environment could be disclosed beyond what this skill actually needs.

Content

Scanner excerpt · scripts/nest.py (reported line 56)May include surrounding context.

python
result = subprocess.run(
                    [op_path, 'item', 'get', item, '--vault', vault, '--format', 'json'],
                    capture_output=True, text=True,
                    env={**os.environ, 'OP_SERVICE_ACCOUNT_TOKEN': op_token}
                )
                if result.returncode == 0:
                    item_data = json.loads(result.stdout)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares no explicit tool/permission scope even though the documentation clearly requires shell access, network access, and environment/secret access. In an agent setting, missing scope boundaries increases the chance the skill is invoked with broader capabilities than users expect, especially given it touches cameras, thermostats, cloud APIs, tunnels, and local services.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The invocation text uses broad natural-language triggers such as monitoring rooms or checking who is at the door, which could match common conversational requests and cause over-selection of a high-privilege home surveillance skill. In agent systems, overly broad routing language can lead to unintended access to cameras, device metadata, or control functions without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill advertises camera feeds, room monitoring, and photo alerts without an explicit privacy warning or notice about transmitting images/events to third parties. In the smart-home context this is more dangerous because the data concerns occupants, visitors, and household activity, making silent or poorly disclosed monitoring particularly sensitive.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 34)May include surrounding context.

md
# 2. Authorize and copy the 'code' parameter from the redirect URL

# 3. Exchange code for tokens:
curl -X POST https://oauth2.googleapis.com/token \
  -d "client_id=CLIENT_ID" \
  -d "client_secret=CLIENT_SECRET" \
  -d "code=AUTH_CODE" \

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation broadens the skill from direct Nest control into an event-forwarding and alerting system involving webhooks, Cloudflare exposure, Clawdbot hooks, and Telegram delivery. That scope expansion materially changes the trust model by moving from user-triggered control to automated surveillance-style event processing and outbound sharing.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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.

Content

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

Generate a token: openssl rand -hex 24

2. Create Pub/Sub Topic

bash
gcloud config set project YOUR_GCP_PROJECT_ID

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 183)May include surrounding context.

bash
# Install cloudflared
curl -L -o ~/.local/bin/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x ~/.local/bin/cloudflared

# Authenticate (opens browser)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

Enable and start:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now nest-webhook cloudflared-nest

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

Enabling services with sudo causes the webhook listener and tunnel to start automatically and persist across reboots, increasing the blast radius of any misconfiguration or compromise. In the context of a smart-home camera/doorbell integration, persistent background network services materially raise exposure beyond one-off device control.

Content

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

bash
sudo systemctl daemon-reload
sudo systemctl enable --now nest-webhook cloudflared-nest

6. Create Pub/Sub Push Subscription

Static analysis

No suspicious patterns detected.