Suspicious — Risk Score 47/100
Last scan:1 day ago Rescan
47 /100
wip-xai-grok
xAI Grok API. Search the web, search X, generate images, generate video.
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.
Skill Namewip-xai-grok
Duration57.2s
Enginepi
Use with caution
Declare the 1Password CLI shell execution in SKILL.md's capabilities section, or use an environment-variable-only credential resolution strategy. The `op read` fallback is a legitimate 1Password integration but must be explicitly declared as it represents shell:WRITE-level access.

Findings 4 items

Severity Finding Location
High
Undeclared shell:WRITE via 1Password CLI execSync Priv Escalation
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.
const key = execSync('op read "op://Agent Secrets/X API/api key"', { stdio: ['pipe', 'pipe', 'pipe'], timeout: 10000 });
→ Declare the 1Password CLI dependency in SKILL.md metadata.dependencies or switch to environment-variable-only credential resolution. If 1Password is intentional, document it explicitly as a required binary dependency.
core.mjs:28
Medium
SKILL.md declares zero dependencies but code requires 1Password CLI Doc Mismatch
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.
dependencies: []
→ Update metadata.dependencies to include 'op (1Password CLI)' if the 1Password integration is intentional, or remove the execSync entirely and rely only on environment variable resolution.
SKILL.md:12
Medium
Silent local filesystem read in edit_image undeclared in docs Sensitive Access
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.
// If it looks like a file path, read and base64 encode
let imageUrl = img;
if (!img.startsWith('http') && !img.startsWith('data:')) {
  const data = readFileSync(img);
→ Document in SKILL.md that edit_image accepts local file paths as images, not just URLs. Declare filesystem:READ in the capability map for this skill.
core.mjs:252
Low
process.env cached with the actual API key value Doc Mismatch
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.
process.env.XAI_API_KEY = key;
→ Be aware that caching API keys in process.env makes them accessible via inspection of the process environment. This is standard practice but worth noting.
core.mjs:33
ResourceDeclaredInferredStatusEvidence
Network READ READ ✓ Aligned core.mjs - all functions call https://api.x.ai/* for legitimate xAI API access
Shell NONE WRITE ✗ Violation core.mjs:28 - execSync('op read "op://Agent Secrets/X API/api key"')
Filesystem NONE READ ✗ Violation core.mjs:252-258 - edit_image reads local file paths and base64-encodes them
Environment NONE READ ✓ Aligned core.mjs:25 - reads XAI_API_KEY from process.env
Skill Invoke NONE NONE No self-invocation detected
10 findings
🔗
Medium External URL 外部 URL
https://console.x.ai/
README.md:29
🔗
Medium External URL 外部 URL
https://clawhub.ai/castanley/grok
README.md:122
🔗
Medium External URL 外部 URL
https://clawhub.ai
README.md:122
🔗
Medium External URL 外部 URL
https://api.x.ai/v1
SKILL.md:8
🔗
Medium External URL 外部 URL
https://docs.x.ai/developers/tools/web-search
SKILL.md:141
🔗
Medium External URL 外部 URL
https://docs.x.ai/developers/tools/x-search
SKILL.md:142
🔗
Medium External URL 外部 URL
https://docs.x.ai/docs/guides/image-generations
SKILL.md:143
🔗
Medium External URL 外部 URL
https://docs.x.ai/docs/guides/video-generations
SKILL.md:144
🔗
Medium External URL 外部 URL
https://opencollective.com/express
package-lock.json:137
🔗
Medium External URL 外部 URL
https://opencollective.com/fastify
package-lock.json:448

File Tree

10 files · 74.2 KB · 2243 lines
JSON 2f · 1183L JavaScript 3f · 733L Markdown 5f · 327L
├─ 📁 _trash
│ └─ 📝 RELEASE-NOTES-v1-0-3.md Markdown 7L · 186 B
├─ 📁 ai
│ └─ 📁 todos
│ └─ 📝 PUNCHLIST.md Markdown 3L · 34 B
├─ 📝 CHANGELOG.md Markdown 43L · 1015 B
├─ 📜 cli.mjs JavaScript 189L · 6.3 KB
├─ 📜 core.mjs JavaScript 389L · 12.6 KB
├─ 📜 mcp-server.mjs JavaScript 155L · 6.1 KB
├─ 📋 package-lock.json JSON 1142L · 39.3 KB
├─ 📋 package.json JSON 41L · 835 B
├─ 📝 README.md Markdown 130L · 3.8 KB
└─ 📝 SKILL.md Markdown 144L · 4.1 KB

Dependencies 2 items

PackageVersionSourceKnown VulnsNotes
@modelcontextprotocol/sdk ^1.27.1 npm No Version loosely pinned with caret. Contains no known vulnerabilities at this version.
op (1Password CLI) any system binary No Not declared in package.json or SKILL.md. Implicit runtime dependency for credential resolution.

Security Positives

✓ All network requests go to legitimate, declared xAI API endpoints (api.x.ai) only
✓ No obfuscation detected — no base64 eval, no dynamic code generation, no anti-analysis patterns
✓ No credential exfiltration — the 1Password read is only used locally to obtain the API key for xAI
✓ No remote code execution or reverse shell patterns present
✓ No access to sensitive paths like ~/.ssh, ~/.aws, or .env files beyond the declared XAI_API_KEY
✓ No hidden instructions in HTML comments or documentation
✓ Package.json has version-pinned dependencies (except SDK peer deps resolved by host)
✓ Input validation present (max limits on domains, handles, image count, etc.)
✓ No data exfiltration — all API calls are to the legitimate xAI service
✓ No supply-chain concerns — @modelcontextprotocol/sdk is a well-known, widely-used package