Back to skill

Security audit

GrayMatter

Security checks for vulnerabilities and agentic risk

Overview

GrayMatter is a disclosed but powerful memory and business-data connector, and its HTTP MCP server can expose credential-backed read/write operations without clear per-caller authentication.

Install only if you trust the publisher and can run it in a tightly scoped setup. Prefer stdio or loopback-only local use, avoid public/tunneled HTTP with a shared VALKYR_AUTH_TOKEN, use least-privilege tokens, validate VALKYR_API_BASE, and review missing helper scripts before granting access to real business data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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 (6)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
mcp-server/index.js:219
Finding

Unauthenticated HTTP MCP Endpoints Can Use the Server Owner's Credentials

Content
View full analysis
apiRequest(context, 'POST', 'MemoryEntry', buildMemoryWritePayload(args))); case 'memory_read': requireString(args.id, 'id'); return execute('memory_read', () => apiRequest(context, 'GET', `MemoryEntry/${encodeURIComponent(args.id)}`)); case 'memory_query': requireString(args.query, 'query'); return execute('memory_query', () => apiRequest(context, 'POST', 'MemoryEntry/query', buildMemoryQueryPayload(args))); case 'graph_get': { const graphPath = args.path ? `SwarmOps/graph/${trimSlashes(args.path)}` : 'SwarmOps/graph'; return execute('graph_get', () => apiRequest(context, 'GET', graphPath)); } case 'entity_list': { requireEntityType(args.entityType); const query = new URLSearchParams(); if (args.limit !== undefined) query.set('limit', String(args.limit)); if (args.offset !== undefined) query.set('offset', String(args.offset)); const suffix = query.toString() ? `?${query}` : ''; return execute('entity_list', () => apiRequest(context, 'GET', `${args.entityType}${suffix}`)); } case 'entity_get': requireEntityType ...[truncated 3640 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
mcp-server/index.js:1009
Finding

Wildcard CORS Allows Arbitrary Websites to Target Credential-Backed MCP Operations

Content
View full analysis
{ res.write(': keepalive\n\n'); }, 25000); req.on('close', () => clearInterval(keepAlive)); } ``` ```js function sendJson(res, status, payload) { res.writeHead(status, { 'access-control-allow-origin': '*', 'access-control-allow-headers': 'authorization,content-type,x-valkyr-token', 'access-control-allow-methods': 'GET,POST,OPTIONS', 'content-type': 'application/json' }); res.end(JSON.stringify(payload)); } function sendNoContent(res) { res.writeHead(204, { 'access-control-allow-origin': '*', 'access-control-allow-headers': 'authorization,content-type,x-valkyr-token', 'access-control-allow-methods': 'GET,POST,OPTIONS' }); res.end(); } ``` ### Technical Analysis Every origin is permitted to access the browser-facing MCP and SSE surfaces. The policy also explicitly permits authorization and custom token headers. Wildcard CORS is especially dangerous when combined with the unauthenticated process-token fallback: an attacker-controlled webpage can attempt to invoke the local server without possessing the ValkyrAI credential. Browser private-network protections may reduce exploitability in some configurations, but they are not an authorization control and do not protect publicly hosted or permissively configured deployments. The server does not validate the `Origin` header, maintain an origin allowlist, or use an independent anti-CSRF/session authorizatio ...[truncated 865 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
mcp-server/index.js:982
Finding

Unbounded JSON Request Buffering Enables Memory-Exhaustion Denial of Service

Content
View full analysis
{ const chunks = []; req.on('data', (chunk) => chunks.push(chunk)); req.on('error', reject); req.on('end', () => { const raw = Buffer.concat(chunks).toString('utf8'); if (!raw) { resolve(null); return; } try { resolve(JSON.parse(raw)); } catch (error) { reject(new Error(`Invalid JSON body: ${error.message}`)); } }); }); } ``` ### Technical Analysis The server stores every incoming request chunk and concatenates the complete body before parsing it. No maximum byte count, request timeout, content-length validation, or streaming parser is used. Because the MCP server is documented for public deployment, a remote party can send oversized or slowly delivered bodies. Multiple concurrent requests can amplify memory consumption and event-loop pressure. ### Attack Path 1. An attacker identifies a reachable `/`, `/message`, or `/mcp` endpoint. 2. The attacker submits one or more extremely large request bodies, or continuously streams data without completing the request. 3. `readJson` retains every received chunk in memory. 4. Concurrent retained buffers increase process memory usage. 5. The Node.js process slows, becomes unresponsive, or terminates because of memory exhaustion. ### Impact Assessment The primary impact is service availability: - MCP operations become unavailable. - In-flight memory and entity operations may fail. - The Node.js process or its container may be terminated. - On shared infrastructure, excessive memory consumption may affect neighboring workloads. No account privilege is required where the HTTP endpoint remains unauthenticated. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/graymatter_api.sh:156
Finding

Configurable Login Helper Output Is Executed Through Shell eval

Content
View full analysis
/dev/null || true)" fi if [[ -z "$login_cmd" || ! -x "$login_cmd" ]]; then return 1 fi eval "$("$login_cmd" env)" TOKEN=${VALKYR_AUTH_TOKEN:-${VALKYR_JWT_SESSION:-}} if [[ -z "$USERNAME" ]] && command -v security >/dev/null 2>&1; then USERNAME=$(keychain_read default "$USERNAME_SERVICE") fi if [[ -z "$PASSWORD" && -n "$USERNAME" ]] && command -v security >/dev/null 2>&1; then PASSWORD=$(keychain_read "$USERNAME" "$PASSWORD_SERVICE") fi } ``` ### Technical Analysis The complete standard output of the selected login command is interpreted as shell source code. Although the expected result is likely a set of environment-variable assignments, no grammar validation or variable allowlist is applied before `eval`. `GRAYMATTER_LOGIN_COMMAND` is environment-configurable, and the fallback may resolve `gm-login` through `PATH`. If either the environment, executable, search path, or helper output is compromised, arbitrary shell syntax executes with the privileges of the user running `graymatter_api.sh`. The surrounding process may have access to Keychain credentials, environment secrets, workspace files, and authenticated API operations. ### Attack Path 1. An attacker influences `GRAYMATTER_LOGIN_COMMAND`, replaces the expected helper, or places a malicious `gm-login` earlier in `PATH`. 2. The malicious helper prints a value such as: ```bash export VALKYR_AUTH_TOKEN="x"; arbitrary_command ``` 3. `run_login` captures the output. 4. `eval` executes both the assignment and injected command. 5. The injected command runs with the invoking user's operating ...[truncated 639 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
mcp-server/index.js:568
Finding

Hosted Account Tokens Can Be Forwarded to an Arbitrary Configured API Origin

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/graymatter_fallback.py:24
Finding

Fallback Memory Records Are Written Without Enforced Private File Permissions

Content
View full analysis
dict: data = load(path) data["timestamp"] = _now_iso() data["status"] = "pending_replay" data.setdefault("items", []).append(item) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8") return data ``` ### Technical Analysis Failed remote memory writes are retained locally for later replay. These payloads may contain private chat content, organizational information, user identifiers, source-channel values, workspace names, or local artifact paths. The implementation relies on the process umask and existing filesystem permissions. It does not create the directory as mode `0700`, enforce file mode `0600`, reject symbolic links, or use an atomic write. An existing permissive file remains permissive. ### Attack Path 1. A GrayMatter write fails and the fallback append function is called. 2. Sensitive memory content is serialized to the configured path. 3. The process runs with a permissive umask, or the target file already has permissive permissions. 4. Another local user or process reads the fallback file. 5. If an attacker can influence the path or pre-create it as a symbolic link, the absence of symlink checks may also permit writing to an unintended user-writable target. ### Impact Assessment The primary impact is local confidentiality loss involving memory content and business context. Exposure is limited to principals that can access the resulting path under operating-system permissions. This finding does not provide evidence of remote exfiltration. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (106)

Tp4

High
Category
MCP Tool Poisoning
Confidence
83% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill presents itself primarily as a memory and schema layer, but operationally it depends on live schema loading and authenticated helper scripts whose exact authority is broader than simple memory access. That can mislead deployment decisions and cause operators to enable a more powerful business-system integration than intended.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/graymatter_api.sh`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/graymatter_api.sh`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/graymatter_api.sh`

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill is designed to retrieve and reuse credentials or session material from macOS/iCloud Keychain and environment variables, then use them for authenticated API access. Credential access is inherently high risk because compromise, over-broad invocation, or prompt injection elsewhere in the agent could turn a memory skill into a pathway for unauthorized access to live organizational data and actions.

Content

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

md
`graymatter_api.sh` uses:
- `VALKYR_API_BASE`, defaulting to `https://api-0.valkyrlabs.com/v1`
- `VALKYR_KEYCHAIN_SERVICE`, defaulting to `VALKYR_AUTH`
- macOS/iCloud Keychain lookup for `VALKYR_AUTH`
- `VALKYR_AUTH_TOKEN` if already present as an override/debug path
- `VALKYR_JWT_SESSION` as a compatible env fallback

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `tmp/api-docs.json`

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document defines GrayMatter Light v1 as a minimal local/offline surface that excludes full graph operations, complex auth, and production-only integrations, but later claims the repo includes RBAC-backed login, workbook APIs, swarm adapters, promotion bridges, and graph-related endpoints. In a security-sensitive agent skill, this mismatch can cause operators or downstream tooling to trust a much smaller attack surface than actually exists, leading to unsafe deployment, under-scoped review, and accidental exposure of higher-risk features.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
91% confidence
Finding

The document explicitly supports a 'reset memory for this chat' trigger, which is a memory manipulation capability. In the context of a durable-memory skill, unauthorized or accidental invocation could change the agent's effective memory state, suppress relevant context, or cause the system to operate from an incomplete brief, materially affecting downstream decisions and actions.

Content

Scanner excerpt · docs/prd-context-compaction-reset.md (reported line 148)May include surrounding context.

md
### User-triggered flow
Examples:
- "reset memory for this chat"
- "start fresh but keep context"
- "compress this thread"

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/graymatter_api.sh (reported line 17)May include surrounding context.

sh
BASE="${VALKYR_API_BASE:-https://api-0.valkyrlabs.com/v1}"
TOKEN=${VALKYR_AUTH_TOKEN:-${VALKYR_JWT_SESSION:-}}
LIGHT_MODE="${GRAYMATTER_LIGHT_MODE:-false}"
KEYCHAIN_SERVICE="${VALKYR_KEYCHAIN_SERVICE:-VALKYR_AUTH}"
USERNAME_SERVICE="${VALKYR_USERNAME_KEYCHAIN_SERVICE:-${KEYCHAIN_SERVICE}_USERNAME}"
PASSWORD_SERVICE="${VALKYR_PASSWORD_KEYCHAIN_SERVICE:-${KEYCHAIN_SERVICE}_PASSWORD}"
USERNAME=${GRAYMATTER_USERNAME:-${VALKYR_USERNAME:-}}

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
mcp-server/index.js:649

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
mcp-server/test/server.test.js:139

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
mcp-server/test/server.test.js:142

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
tests/gm_install_check_test.sh:43

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
tests/gm_login_test.sh:169