139 lines
3.9 KiB
Markdown
139 lines
3.9 KiB
Markdown
# Token Prefix Security Recommendations
|
|
|
|
## Current Security Issues
|
|
|
|
### 1. Information Disclosure
|
|
- Prefixes like "KMS", "TEST", "PROD" expose system architecture
|
|
- Makes it easy for attackers to identify token origins and purposes
|
|
- Leaks information about internal applications and environments
|
|
|
|
### 2. Predictable Token Structure
|
|
- Static tokens: `PREFIX + "T-" + token_data`
|
|
- User tokens: `PREFIX + "UT-" + jwt_token`
|
|
- Highly predictable format aids in token identification and potential attacks
|
|
|
|
### 3. Application Fingerprinting
|
|
- Trivial to map tokens to specific applications
|
|
- Easy to identify different environments (dev/staging/prod)
|
|
- Reveals system architecture from leaked tokens
|
|
|
|
## Recommended Security Improvements
|
|
|
|
### Option 1: Remove Custom Prefixes (Recommended)
|
|
```go
|
|
// Use a single, non-descriptive prefix for all tokens
|
|
const SecureTokenPrefix = "kms_"
|
|
|
|
// All tokens would be: kms_<random_data>
|
|
// No application or type information revealed
|
|
```
|
|
|
|
### Option 2: Opaque Application Identifiers
|
|
```go
|
|
// Use random/hashed identifiers instead of descriptive names
|
|
type Application struct {
|
|
AppID string `json:"app_id"`
|
|
TokenPrefix string `json:"token_prefix"` // Random: "A7B2", "X9K5", etc.
|
|
}
|
|
|
|
// Generate random 4-character prefixes
|
|
func GenerateSecurePrefix() string {
|
|
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
result := make([]byte, 4)
|
|
for i := range result {
|
|
result[i] = charset[rand.Intn(len(charset))]
|
|
}
|
|
return string(result)
|
|
}
|
|
```
|
|
|
|
### Option 3: No Type Indicators
|
|
```go
|
|
// Remove "T-" and "UT-" type indicators
|
|
// Token type should be determined by validation, not structure
|
|
func GenerateToken(appPrefix string, tokenType string) string {
|
|
token := appPrefix + randomTokenData // No type suffix
|
|
return token
|
|
}
|
|
```
|
|
|
|
### Option 4: Encrypted Token Metadata
|
|
```go
|
|
// Encrypt sensitive information within tokens
|
|
type TokenMetadata struct {
|
|
AppID string `json:"app_id"`
|
|
TokenType string `json:"token_type"`
|
|
IssuedAt time.Time `json:"issued_at"`
|
|
}
|
|
|
|
func CreateSecureToken(metadata TokenMetadata, key []byte) string {
|
|
// Encrypt metadata and embed in token
|
|
encrypted := encrypt(metadata, key)
|
|
return "kms_" + base64.URLEncoding.EncodeToString(encrypted)
|
|
}
|
|
```
|
|
|
|
## Implementation Priority
|
|
|
|
1. **Immediate**: Remove descriptive prefixes ("KMS", "TEST", "PROD")
|
|
2. **Short-term**: Remove type indicators ("T-", "UT-")
|
|
3. **Long-term**: Implement encrypted token metadata
|
|
|
|
## Security Best Practices
|
|
|
|
### Token Storage
|
|
- Always hash tokens before database storage
|
|
- Use strong hashing algorithms (bcrypt, scrypt, Argon2)
|
|
- Never log or expose full tokens
|
|
|
|
### Token Validation
|
|
- Validate tokens by content, not by prefix patterns
|
|
- Use cryptographic verification for all tokens
|
|
- Implement proper token revocation mechanisms
|
|
|
|
### Monitoring
|
|
- Monitor for token enumeration attempts
|
|
- Alert on suspicious prefix-based attacks
|
|
- Log token validation failures for security analysis
|
|
|
|
## Code Changes Required
|
|
|
|
### 1. Update Token Generation
|
|
```go
|
|
// Before: Predictable structure
|
|
token := "TESTT-" + tokenData
|
|
|
|
// After: Opaque structure
|
|
token := "kms_" + secureRandomToken()
|
|
```
|
|
|
|
### 2. Update Validation Logic
|
|
```go
|
|
// Before: Prefix-based type detection
|
|
if strings.HasPrefix(token, app.TokenPrefix + "UT-") {
|
|
return TokenTypeUser
|
|
}
|
|
|
|
// After: Cryptographic validation
|
|
tokenType, err := validateAndExtractType(token, app.HMACKey)
|
|
```
|
|
|
|
### 3. Database Migration
|
|
```sql
|
|
-- Remove descriptive prefixes from existing tokens
|
|
UPDATE applications
|
|
SET token_prefix = 'kms_'
|
|
WHERE token_prefix IN ('KMS', 'TEST', 'PROD', 'DEV');
|
|
```
|
|
|
|
## Risk Assessment
|
|
|
|
**Current Risk Level**: HIGH
|
|
- Token structure reveals sensitive system information
|
|
- Easy application and environment fingerprinting
|
|
- Predictable token patterns aid in attacks
|
|
|
|
**Mitigated Risk Level**: LOW
|
|
- Opaque token structure prevents information leakage
|
|
- No application or environment identification possible
|
|
- Cryptographic validation ensures security |