T05 · Unauthorized Access and Privilege Escalation
- Location
src/index.ts:90- Finding
Forgeable and Replayable Grill Authorization Tokens
- Content
View full analysis
f.endsWith(".token") ); const now = Date.now() / 1000; for (const file of files) { const filePath = join(config.tokenDir, file); try { const content = readFileSync(filePath, "utf-8"); const data = JSON.parse(content); if (now - (data.issued_at || 0) < config.tokenTtlSeconds) { return true; // Valid token found } // Expired — clean up unlinkSync(filePath); } catch { try { unlinkSync(filePath); } catch {} } } return false; } catch { return false; } } ``` The result is used as the authorization boundary for restricted tool calls: ```ts if (isBlockedCommand(command, config)) { if (!hasValidToken(config)) { return { block: true, blockReason: "🛑 Grill Gate: Blocked command detected without grill token. " + "You must complete a grill-with-docs session first, then issue a " + "grill token via: python3 scripts/auto_dispatch.py --issue-grill-token ''", }; } } ``` ### Technical Analysis The gate treats any file ending in `.token` as a valid authorization token when its JSON content has an `issued_at` value satisfying: ```ts now - issued_at < tokenTtlSeconds ``` No cryptographic signature, message authentication code, unpredictable secret, trusted issuer identifier, strict schema, or task binding is validated. Consequently, any process or agent able to write into the configured token directory can create its own authorization token without completing ...[truncated 2126 chars]- Remediation
View remediation
