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

3.9 KiB

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
// 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

// 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

// 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

// 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

// Before: Predictable structure
token := "TESTT-" + tokenData

// After: Opaque structure  
token := "kms_" + secureRandomToken()

2. Update Validation Logic

// 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

-- 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