Weak OAuth state generation uses Math.random() (CWE-330) — fixed in PR #33
- Dominant language
- TypeScript
- Stars
- 134
- Forks
- 64
- PR merge metrics
- No merged PRs in 30d
Description
## Weak OAuth `state` generation (non-cryptographic PRNG) — `src/auth.ts`
**Severity:** Low–Moderate (info-grade security weakness; defense-in-depth, not directly-remote RCE in the local/PAT flow)
**File:** `src/auth.ts:220-222`
```ts
private generateState(): string {
return Math.random().toString(36).substring(2, 15);
}
```
`generateState()` feeds the OAuth `state` anti-CSRF parameter (RFC 6749 s4.1.1) via `getAuthorizationUrl()` (`state: this.generateState()`). `Math.random()` is a PRNG (V8 xorshift128+, seeded from the current time) — predictable, not cryptographically secure. `state` must be unguessable and bound to a single login attempt (this repo's issue #24 already documents that state is a "unique security key for a single login attempt"). No CSPRNG is used anywhere in the repo.
**Impact (honest scope):** low-to-moderate. Local stdio MCP server; primary auth is a Linear PAT. OAuth state-fixation/CSRF is not a directly-remote RCE here, but it is a genuine defect in a security-critical parameter and should be hardened regardless (CWE-330).
**Fix (PR #33):** `crypto.randomUUID()` — CSPRNG, zero deps.
**Verification:** static/code-level; deterministic, reproducible from the committed source.
Contributor guide
No contributing guide indexed for this repository
Research direction
Inspect src/auth.ts:220-222 and the getAuthorizationUrl() entry point to confirm how the OAuth state is generated and used. Review PR #33 and verify the committed source no longer uses a non-cryptographic generator; completion is a deterministic static check of that change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication, security
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 20/100