Files
skybridge/SECURITY_RECOMMENDATIONS.md
2025-08-26 13:51:15 -04:00

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