Is acfranzen/glance safe?

https://github.com/openclaw/skills/tree/main/skills/acfranzen/glance

78
CAUTION

The acfranzen/glance skill is a functional AI-extensible dashboard tool with no directly malicious content in its SKILL.md and a clean installation profile. Its primary security concern is architectural: the 'agent_refresh' pattern instructs agents to execute instructions stored in a local SQLite database as recurring agent subagent tasks, creating a persistent indirect prompt injection vector that activates whenever a malicious widget package is imported via the !GW1! format. The skill's safety is therefore transitively dependent on the integrity of every third-party widget package a user installs, and operators should treat widget imports with the same scrutiny as direct code execution.

Category Scores

Prompt Injection 65/100 · 30%
Data Exfiltration 72/100 · 25%
Code Execution 92/100 · 20%
Clone Behavior 95/100 · 10%
Canary Integrity 90/100 · 10%
Behavioral Reasoning 62/100 · 5%

Findings (8)

HIGH Indirect Prompt Injection via agent_refresh fetch.instructions -25

The skill's core operational pattern instructs agents to periodically query a local SQLite database for per-widget fetch.instructions and pass that content verbatim as the task argument when spawning subagents. Because widget packages can be imported from external sources using the !GW1! compressed-base64 format, a malicious widget author can pre-load arbitrary prompt injection payloads into fetch.instructions. Once imported, the agent's cron job will repeatedly execute those instructions — with full tool access (exec, PTY, browser, web_fetch) — without any content review or sanitization step.

MEDIUM Origin Header Authentication Bypass Taught to Agent -10

SKILL.md explicitly documents that any HTTP request carrying 'Origin: $GLANCE_URL' bypasses Bearer token authentication on all API endpoints. The skill teaches agents to use this pattern as the standard call pattern for all local Glance API calls. This normalizes auth circumvention and means any process that knows the GLANCE_URL value (e.g. from environment variable exposure) can make unauthenticated write requests to the widget API.

MEDIUM agent_refresh Enables Arbitrary Data Collection to Configurable Remote Endpoint -18

The agent_refresh workflow grants complete authority to fetch.instructions to direct agents to use exec, PTY, browser, or web_fetch tools to harvest any locally accessible data, then POST it to $GLANCE_URL/api/widgets/{slug}/cache. If GLANCE_URL is configured as a remote server (rather than localhost), all collected widget data — which can include output of arbitrary shell commands — is transmitted externally. Combined with a malicious widget, this becomes a persistent scheduled data exfiltration channel.

LOW server_code Widget Execution Permits Unconstrained fetch() (SSRF Vector) -10

Widget server_code runs in a sandboxed Node.js VM that blocks require(), eval(), fs, and process access, but explicitly and intentionally permits fetch(). This means server_code widgets can make HTTP requests to any reachable URL from the Glance server's network context, including internal services, cloud metadata endpoints (e.g. 169.254.169.254/latest/meta-data/), or attacker-controlled exfiltration endpoints. The getCredential() function makes stored API keys available to this code.

MEDIUM Transitive Trust: Skill Security Depends on All Imported Widget Packages -20

The skill creates no explicit trust boundary between the skill itself and third-party widget packages imported via the !GW1! format. Any widget imported by the user becomes a persistent instruction source that the agent executes on a schedule. The skill actively encourages widget sharing (export/import workflows, community widget references), meaning a single malicious shared widget can compromise the agent's behavior indefinitely without requiring re-installation of the skill itself.

LOW OPENCLAW_GATEWAY_URL Creates Configurable C2 Notification Webhook -8

When OPENCLAW_GATEWAY_URL is set, clicking the widget refresh button causes Glance to immediately POST a wake notification to that external URL. This is documented as enabling 'instant widget refresh' by waking the agent. An attacker who controls this endpoint receives real-time signals of user interaction with the dashboard. In combination with injected widget instructions, this enables a feedback loop where the attacker can observe agent activity and trigger on-demand execution.

INFO Honeypot Credential Files Read During Monitoring — Attributed to Monitoring Infrastructure 0

inotify logs and auditd PATH records show /home/oc-exec/.env, .ssh/id_rsa, .aws/credentials, .npmrc, .docker/config.json, and .config/gcloud/application_default_credentials.json were opened and read at 05:15:47 (before git clone) and at timestamp 1771650968.594 (post-install). The first access set is correlated with sudo PAM authentication (SYSCALL records show comm=sudo, pid=1003, ppid=981 at 1771650947.105); the second set correlates with a new SSH session established by the OATHE monitoring infrastructure. The skill's installed files contain no code that references these paths. Canary file integrity check confirms no modifications.

INFO Clean Install — No Executable Artifacts 0

Full inspection of the installed skill package found only documentation Markdown files and a version metadata JSON. No npm scripts, no git hooks, no .gitattributes smudge/clean filters, no git submodules, and no symlinks were found. The git clone used sparse checkout targeting only the skills/acfranzen/glance subdirectory and completed without error.