wip-xai-grok
Skill executes undeclared shell commands via 1Password CLI to resolve credentials without declaring shell:WRITE permission in SKILL.md, creating a doc-to-code mismatch on the most sensitive operation.
The resolveApiKey() function uses Node.js execSync to execute 'op read "op://Agent Secrets/X API/api key"', which is a shell command. This provides shell:WRITE capability but is not declared anywhere in SKILL.md's capabilities, metadata.dependencies, or allowed-tools mapping. The SKILL.md metadata shows dependencies: [] but the code has an implicit dependency on the 1Password CLI binary (op). While the README.md mentions this, SKILL.md is the canonical capability declaration and is silent on this.
core.mjs:28 为什么得出这个结论
2/4 个维度触发发现 2 项声明之外的能力或越权行为。
提取到 10 个一般风险产物,需要结合上下文判断。
报告包含 0 步攻击链,另有 1 项高危或严重发现。
发现 1 项需要关注的依赖或供应链线索。
风险分是怎么被拉高的
core.mjs:28 uses execSync to call 'op read' CLI (1Password) for credential resolution. This is shell:WRITE access not declared in SKILL.md capabilities or metadata.dependencies
The 1Password CLI integration reads secrets from a password manager, but the execSync call itself is undeclared shell access that could be swapped for arbitrary commands
SKILL.md metadata shows 'dependencies: []' yet core.mjs imports node:child_process for shell execution
edit_image() silently reads local files and base64-encodes them (core.mjs:252-258). SKILL.md describes image editing as URL-only without mentioning local filesystem access
最关键的证据
Undeclared shell:WRITE via 1Password CLI execSync
The resolveApiKey() function uses Node.js execSync to execute 'op read "op://Agent Secrets/X API/api key"', which is a shell command. This provides shell:WRITE capability but is not declared anywhere in SKILL.md's capabilities, metadata.dependencies, or allowed-tools mapping. The SKILL.md metadata shows dependencies: [] but the code has an implicit dependency on the 1Password CLI binary (op). While the README.md mentions this, SKILL.md is the canonical capability declaration and is silent on this.
core.mjs:28 SKILL.md declares zero dependencies but code requires 1Password CLI
SKILL.md metadata shows 'dependencies: []' and the skill is described as requiring only XAI_API_KEY. However, the implementation silently requires the 'op' (1Password CLI) binary to be installed. The 1Password path 'op://Agent Secrets/X API/api key' is hardcoded with no fallback notice to the user. If 1Password is unavailable and XAI_API_KEY is not set, the error message is opaque.
SKILL.md:12 Silent local filesystem read in edit_image undeclared in docs
edit_image() accepts image file paths (not just URLs) and silently reads them from disk using readFileSync, base64-encodes them, and sends to the xAI API (core.mjs:252-258). SKILL.md describes edit_image as requiring a 'URL or base64 data URI' but never mentions that local file paths are also silently accepted and read. The function has filesystem:READ access that is neither declared in capabilities nor documented in the function description.
core.mjs:252 process.env cached with the actual API key value
resolveApiKey() caches the retrieved 1Password secret into process.env.XAI_API_KEY (core.mjs:33), meaning subsequent calls won't need the execSync but the key will live in the environment. This is a minor info-leak risk if the process memory is exposed.
core.mjs:33 声明能力 vs 实际能力
core.mjs - all functions call https://api.x.ai/* for legitimate xAI API access core.mjs:28 - execSync('op read "op://Agent Secrets/X API/api key"') core.mjs:252-258 - edit_image reads local file paths and base64-encodes them core.mjs:25 - reads XAI_API_KEY from process.env No self-invocation detected 可疑产物与外联
https://console.x.ai/ README.md:29
https://clawhub.ai/castanley/grok README.md:122
https://clawhub.ai README.md:122
https://api.x.ai/v1 SKILL.md:8
https://docs.x.ai/developers/tools/web-search SKILL.md:141
https://docs.x.ai/developers/tools/x-search SKILL.md:142
https://docs.x.ai/docs/guides/image-generations SKILL.md:143
https://docs.x.ai/docs/guides/video-generations SKILL.md:144
https://opencollective.com/express package-lock.json:137
https://opencollective.com/fastify package-lock.json:448
依赖与供应链
| 包名 | 版本 | 来源 | 漏洞 | 备注 |
|---|---|---|---|---|
| @modelcontextprotocol/sdk | ^1.27.1 | npm | 否 | Version loosely pinned with caret. Contains no known vulnerabilities at this version. |
| op (1Password CLI) | any | system binary | 否 | Not declared in package.json or SKILL.md. Implicit runtime dependency for credential resolution. |
文件构成
package-lock.json core.mjs SKILL.md README.md