Skip to content

fix(security): CSPRNG for PKCE/state + OAuth improvements#1030

Open
AlexZander85 wants to merge 7 commits intoRightNow-AI:mainfrom
AlexZander85:feature/oauth-providers
Open

fix(security): CSPRNG for PKCE/state + OAuth improvements#1030
AlexZander85 wants to merge 7 commits intoRightNow-AI:mainfrom
AlexZander85:feature/oauth-providers

Conversation

@AlexZander85
Copy link
Copy Markdown
Contributor

Summary

Fixes critical security vulnerabilities found in security audit of #1025.

Security Fixes (CRITICAL)

  • PKCE code verifier: Replace SystemTime-based pseudo-random with OsRng (256-bit CSPRNG)
  • OAuth state parameter: Replace SystemTime with OsRng (128-bit CSPRNG)
  • Both now use
    and::rngs::OsRng.fill_bytes()\ per RFC 7636 and RFC 6749

Changes

  • \generate_pkce(): 32 bytes from OsRng → base64url (43 chars)
  • \generate_state(): 16 bytes from OsRng → base64url
  • Added uniqueness tests to verify CSPRNG behavior
  • Clarified MiniMax stub error messages

Testing

\\�ash
cargo test -p openfang-runtime -- oauth

6 tests passed including pkce_uniqueness and state_uniqueness

\\

Addresses Audit Findings

  • ✅ CRITICAL: Weak PKCE code verifier generation (fixed)
  • ✅ CRITICAL: Weak state parameter generation (fixed)
  • ✅ MiniMax stub clarified (error messages updated)

Co-authored-by: Security Audit security@openfang.sh

Ports OAuth authentication from ZeroClaw:
- OpenAI Codex (ChatGPT subscription) - device code flow + PKCE
- Gemini (Google OAuth) - device code flow
- Qwen (Alibaba) - reads from ~/.qwen/oauth_creds.json
- MiniMax - refresh token based authentication

Implements:
- Device code start/poll functions for each provider
- PKCE code verifier/challenge generation
- Token refresh logic
- OAuthTokenSet struct for vault storage

Note: Full workspace build blocked by pre-existing mcp.rs error
(StreamableHttpClientTransportConfig non-exhaustive struct)
… mcp.rs

- Fix mcp.rs StreamableHttpClientTransportConfig non-exhaustive struct
- Add oauth_providers.rs with device code flows for 4 OAuth providers
- Add API routes for OAuth start/poll endpoints in server.rs and routes.rs
- Add OAuth UI buttons to settings.js dashboard
- Add OAuth provider configs to drivers/mod.rs with oauth_provider field
- Update index_body.html with OAuth login buttons for each provider
- Replace SystemTime-based pseudo-random with OsRng
- generate_pkce() now uses rand::rngs::OsRng.fill_bytes()
- generate_state() now uses OsRng (128-bit entropy)
- Fix MiniMax stub with clearer error messages
- Add tests for uniqueness (CSPRNG verification)

Addresses security audit findings:
- CRITICAL: Weak PKCE code verifier generation
- CRITICAL: Weak state parameter generation
…docs

- OAuth /start endpoints now cost 100 tokens (prevents device code spam)
- OAuth /poll endpoints cost 1 token (normal polling)
- Clarified Qwen is file-based token import, not true OAuth flow
- Added rate limiter tests for OAuth endpoints
- Updated module docs to explain Qwen and MiniMax limitations
- Resolve merge conflicts in drivers/mod.rs, mcp.rs, index_body.html
- Add oauth_provider field to ProviderDefaults struct
- Fix clippy: &PathBuf -> &Path, unnecessary_cast, redundant_closure,
  collapsible_if, manual_contains, dead_code warnings
- Add missing novita/novita-ai provider defaults entry
- Fix huggingface env var: HF_API_KEY -> HF_TOKEN (match upstream)
- Remove orphaned i18n routes (not in this PR scope)
- Fix unused variable warnings in OAuth route handlers
- Apply cargo fmt
@AlexZander85
Copy link
Copy Markdown
Contributor Author

⚠️ Security Audit — pre-existing vulnerabilities, not introduced by this PR

The cargo audit failures are all pre-existing in main and not caused by this PR's changes:

Advisory Severity Affected crate Fix
RUSTSEC-2026-0095 🔴 Critical wasmtime 41.0.4 (Winch sandbox escape) Upgrade to ≥42.0.2
RUSTSEC-2026-0049 Medium rustls-webpki 0.102.8 (CRL matching) Upgrade to ≥0.103.10
RUSTSEC-2026-0097 Low rand 0.7/0.8/0.9 (unsound with custom logger) Indirect deps
RUSTSEC-2025-0134 Info rustls-pemfile 2.2.0

The critical one (wasmtime) is a major version bump that may break the sandbox API and should be handled in a separate dedicated PR. All other CI checks (build, test, clippy, fmt) pass on all platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant