Get Form Token
Obtain an HMAC-signed form token for submitting protected forms (waitlist, feedback).
Endpoint
Authentication
No authentication required, but must be same-origin request.
Security Requirements
- Must be same-origin request (checked via
Origin header)
Response
HMAC-signed form token. Format: {nonce}.{timestamp}.{signature}
nonce: 32-character hex string (16 bytes of randomness)
timestamp: Unix timestamp in milliseconds
signature: 64-character HMAC-SHA256 signature
Token Expiry
Tokens are valid for 10 minutes from issuance. After expiry, requests using the token will be rejected with a 400 error.
Error Responses
403 Forbidden
- Cross-origin request blocked
500 Internal Server Error
FORM_TOKEN_SECRET environment variable not configured
- Token generation failed
Example
curl https://umbra.concrete-security.com/api/form-token \
-H "Origin: https://umbra.concrete-security.com"
Success Response
{
"token": "a1b2c3d4e5f67890123456789abcdef0.1709654400000.8f3a2b1c4d5e6f7890123456789abcdef01234567890abcdef1234567890abcd"
}
Error Response
{
"error": "Unable to issue a form token. Please try again later."
}
Token Verification
When a form is submitted with a token, the server verifies:
- Format: Token must have exactly 3 parts separated by dots
- Completeness: All parts (nonce, timestamp, signature) must be present
- Timestamp: Must be a valid number
- Expiry: Token must not be older than 10 minutes
- Signature: HMAC-SHA256 signature must match using
FORM_TOKEN_SECRET
Verification uses constant-time comparison to prevent timing attacks.
Token Structure
{nonce}.{timestamp}.{signature}
Example breakdown:
- Nonce:
a1b2c3d4e5f67890123456789abcdef0 (32 hex chars)
- Timestamp:
1709654400000 (milliseconds since epoch)
- Signature:
8f3a2b1c4d5e6f7890123456789abcdef01234567890abcdef1234567890abcd (64 hex chars)
The signature is computed as:
HMAC-SHA256(nonce + "." + timestamp, FORM_TOKEN_SECRET)
Implementation Details
Form tokens provide anti-bot protection without requiring CAPTCHA. They ensure requests originate from the legitimate frontend and not from automated scripts.
The FORM_TOKEN_SECRET environment variable must be configured and kept secure. It’s used to sign and verify all form tokens.
Usage Pattern
- Frontend: Request token from
/api/form-token
- Frontend: Include token in form submission to
/api/waitlist or /api/feedback
- Backend: Verify token signature and expiry
- Backend: Process form if valid, reject if invalid/expired
Tokens are single-use in practice due to the short expiry window and rate limiting on form submission endpoints.
Source: frontend/app/api/form-token/route.ts and frontend/lib/security/form-token.ts