Files
StarFleetCPTN 31871bd16e feat: Implement storage provider management functionality
- Added new routes and handlers for managing storage providers, including creation, editing, and deletion.
- Introduced a new StorageProvider form component for user input.
- Enhanced the database schema to support storage provider references in transfer configurations.
- Implemented encryption for sensitive fields in storage provider data.
- Added tests for storage provider API endpoints and integration with the database.
- Updated frontend components to support storage provider selection and testing.
2025-04-16 17:18:53 -07:00

104 lines
3.1 KiB
Go

package encryption
import (
"regexp"
"strings"
)
// SanitizeError sanitizes an error message to remove or mask sensitive data like keys
func SanitizeError(errMsg string) string {
if errMsg == "" {
return ""
}
// Sanitize any hex keys (likely to be encryption keys)
hexKeyPattern := regexp.MustCompile(`([0-9a-fA-F]{16,})`)
errMsg = hexKeyPattern.ReplaceAllStringFunc(errMsg, func(match string) string {
if len(match) > 8 {
return match[:4] + "..." + match[len(match)-4:]
}
return "****"
})
// Sanitize any base64 content that might contain keys or encrypted data
base64Pattern := regexp.MustCompile(`([A-Za-z0-9+/]{16,}={0,2})`)
errMsg = base64Pattern.ReplaceAllStringFunc(errMsg, func(match string) string {
if len(match) > 8 {
return match[:4] + "..." + match[len(match)-4:]
}
return "****"
})
// Mask content that appears to be formatted like encryption keys
keyPattern := regexp.MustCompile(`(?i)key[=:][\s]*["']?([^"'\s]+)["']?`)
errMsg = keyPattern.ReplaceAllString(errMsg, "key=****")
// Mask any JWT tokens
jwtPattern := regexp.MustCompile(`eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+`)
errMsg = jwtPattern.ReplaceAllString(errMsg, "JWT_TOKEN_REDACTED")
// Mask content that appears to be passwords or secrets
secretPattern := regexp.MustCompile(`(?i)(password|secret|token|auth)[=:][\s]*["']?([^"'\s]+)["']?`)
errMsg = secretPattern.ReplaceAllString(errMsg, "$1=****")
// Remove any content between our encrypted prefix and the end of the word
encPrefix := EncryptedPrefix
if encPrefix != "" {
errMsg = sanitizeEncryptedValues(errMsg, encPrefix)
}
return errMsg
}
// sanitizeEncryptedValues replaces encrypted values with a redacted placeholder
func sanitizeEncryptedValues(input, prefix string) string {
if prefix == "" {
return input
}
// Find all occurrences of the prefix and replace the entire encrypted value
parts := strings.Split(input, prefix)
if len(parts) <= 1 {
return input
}
result := parts[0]
for i := 1; i < len(parts); i++ {
part := parts[i]
// Find the end of the encrypted value (usually a space, comma, period, quote, etc.)
endIdx := strings.IndexAny(part, " \t\n\r.,;:\"')")
if endIdx == -1 {
// If no terminating character, take the whole string
result += prefix + "****"
} else {
// Keep the terminating character
result += prefix + "****" + part[endIdx:]
}
}
return result
}
// SanitizeCredentialData removes or masks a credential for safe logging
// This is a utility function to use in error messages and logs
func SanitizeCredentialData(value string) string {
if value == "" {
return ""
}
// If already an encrypted value, return just the prefix and a hint of the actual value
if strings.HasPrefix(value, EncryptedPrefix) {
encrypted := strings.TrimPrefix(value, EncryptedPrefix)
if len(encrypted) > 8 {
return EncryptedPrefix + encrypted[:4] + "..." + encrypted[len(encrypted)-4:]
}
return EncryptedPrefix + "..."
}
// For plaintext credentials, just mask the value entirely
if len(value) > 8 {
return value[:2] + "..." + value[len(value)-2:]
}
return "****"
}