-
Notifications
You must be signed in to change notification settings - Fork 3
refactor: migrate captcha to stateless JWT-based design #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
LaurenceJJones
wants to merge
8
commits into
main
Choose a base branch
from
refactor-captcha-stateless
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Replace stateful UUID-based session management with stateless signed cookies - Implement CaptchaToken with UUID, status, issued/expiration timestamps - Add SignCaptchaToken and ParseAndVerifyCaptchaToken for cookie signing - Move token/cookie operations to Captcha struct methods (NewPendingToken, NewPassedToken, GenerateCookie, ValidateCookie) - Add per-host configuration for pending_ttl, passed_ttl, and cookie_secret - Remove global session manager and all session-related code - Remove SignCookies configuration (cookies always signed for stateless design) - Fix redirect loop by only redirecting on pending→valid transition - Simplify logic by removing unnecessary flags (needsNewCookie, captchaStatus) - Add UUID tracking throughout for better debugging and traceability - Update HAProxy config to use %[url] for redirects instead of stored URL - Clean up dead code and duplicated functionality
- Move CookieGenerator struct and methods from internal/cookie to internal/remediation/captcha - Remove internal/cookie package as it was only used by captcha - All cookie-related functionality now lives in the captcha package - Simplifies codebase by removing unnecessary package separation - Add .vagrant/ to .gitignore
9b06567 to
5960d50
Compare
- Replace custom payload.sig format with standard JWT using golang-jwt/jwt/v4 - Use HMAC-SHA256 signing (JWS) for token integrity - Remove double-encoding: JWT tokens are already base64url-encoded - Update ValidateCaptchaCookie to work directly with JWT format - Maintain backward compatibility: old format cookies automatically trigger new JWT cookie creation - Future-proof: JWT enables easy addition of encryption (JWE) and additional claims (e.g., client fingerprinting) Benefits: - Standard, well-audited format (RFC 7519) - Automatic expiration handling via JWT library - Ready for future encryption needs (JWE) for sensitive data - Can easily add claims like IP hash, user-agent hash to prevent cookie reuse
….3.0) - Remove default fallback to secret_key for cookie_secret - Require explicit cookie_secret configuration (breaking change) - Enforce minimum 32 bytes for cookie_secret security - Fail fast with clear error messages at initialization - Update documentation to reflect required field - Update example configs with cookie_secret requirement This change ensures: - Compliance: separate secrets for captcha provider and cookie signing - Security: minimum 32 bytes enforced for cryptographic strength - Multi-instance: explicit configuration required for shared cookies - Clarity: clear error messages guide users to proper configuration
- Remove GetCookieSecret() getter method from Captcha struct - Use direct property access (c.CookieSecret) in GenerateCookie() and ValidateCookie() - Simplifies code by removing unnecessary abstraction layer
- Replace string concatenation with single strings in error messages - Update README to use hex encoding for cookie_secret generation - Use openssl rand -hex 32 for clearer byte count visibility
45246a2 to
593c2af
Compare
- Remove .vagrant files from git index (files remain on disk) - .vagrant/ should be ignored via .gitignore (handled in separate PR)
- Merge main branch to include .gitignore changes (.vagrant/ addition)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Pull Request: Refactor Captcha to Stateless JWT-Based Design
Summary
Refactors the captcha system from a stateful, UUID-based session design to a stateless, JWT-based signed cookie design. Removes all server-side session storage and consolidates cookie handling into the captcha package.
Key Changes
1. Stateless Token Design
CaptchaTokenwith UUID, status, issued/expiration timestamps2. JWT Migration
payload.sigformat to standard JWT (JWS) usinggolang-jwt/jwt/v43. Code Consolidation
CookieGeneratorfrominternal/cookietointernal/remediation/captchainternal/cookiepackage (only used by captcha)internal/sessionpackage (no longer needed)4. Encapsulation & Configuration
Captchastruct:NewPendingToken(),NewPassedToken(),GenerateCookie(),ValidateCookie()pending_ttl,passed_ttl,cookie_secretSignCookiesconfig (cookies always signed for stateless design)5. Logic Improvements
needsNewCookie,captchaStatustrackinginitialStatusinstead of boolean flags6. HAProxy Integration
%[url]for redirects (no server-side URL tracking)redirect = "1"flag for HAProxy to handle redirects7. Backward Compatibility
Benefits
Technical Details
uuid,st(status),iat,expgithub.com/golang-jwt/jwt/v4as direct dependencyTesting
Breaking Changes
Haproxy configuration now handles the redirect based on the boolean flag
cookie_secretis now mandatory property that must be set by the user configuration on the host