Files
viettranx 611377a57e test: improve test quality with concurrent tests and security validation
- Add concurrent tests for session, memory, agent stores (race detection)
- Add task lifecycle edge case tests (BlockedUnblockFlow, RaceToClaimSameTask)
- Strengthen scrub_test.go assertions to verify exact output
- Add security edge case validation to ValidateUserID (null bytes, control chars, unicode format chars)
2026-04-12 21:05:10 +07:00

45 lines
1.3 KiB
Go

package store
import (
"fmt"
"strings"
"unicode"
)
// MaxUserIDLength is the maximum allowed length for user identifier strings
// (user_id, owner_id, granted_by, requested_by, reviewed_by, etc.).
// Matches the VARCHAR(255) constraint in the database schema.
const MaxUserIDLength = 255
// ValidateUserID validates user identifiers for length and dangerous characters.
// Defense-in-depth: SQL injection is handled by parameterized queries, but we
// also reject clearly malicious patterns at the validation layer.
func ValidateUserID(id string) error {
if len(id) > MaxUserIDLength {
return fmt.Errorf("user identifier too long: %d chars (max %d)", len(id), MaxUserIDLength)
}
// Reject null bytes
if strings.ContainsRune(id, '\x00') {
return fmt.Errorf("user identifier contains null byte")
}
// Reject control characters (below space, including tab/newline/carriage return)
for _, r := range id {
if r < 32 {
return fmt.Errorf("user identifier contains control character: %U", r)
}
// Reject dangerous unicode categories
if unicode.Is(unicode.Cf, r) { // Format characters (ZWJ, RTL override, etc.)
return fmt.Errorf("user identifier contains format character: %U", r)
}
}
// Reject BOM
if strings.HasPrefix(id, "\uFEFF") {
return fmt.Errorf("user identifier starts with BOM")
}
return nil
}