diff --git a/.changeset/sip-encrypted-header-values.md b/.changeset/sip-encrypted-header-values.md new file mode 100644 index 000000000..33b3ee745 --- /dev/null +++ b/.changeset/sip-encrypted-header-values.md @@ -0,0 +1,5 @@ +--- +"github.com/livekit/protocol": patch +--- + +Allow SIP header values with the `lkenc:` prefix up to 8192 characters, so that encrypted header values pass validation diff --git a/livekit/sip_validation.go b/livekit/sip_validation.go index 99859a496..098cec833 100644 --- a/livekit/sip_validation.go +++ b/livekit/sip_validation.go @@ -246,6 +246,14 @@ func ValidateHeaderName(name string, restrictNames bool) error { return nil } +// EncryptedHeaderValuePrefix marks a header value that was encrypted. +const EncryptedHeaderValuePrefix = "lkenc:" + +const ( + maxHeaderValueLen = 1024 + maxEncryptedHeaderValueLen = 8192 +) + // ValidateHeaderValue validates a SIP header value per RFC 3261 Section 25.1 func ValidateHeaderValue(name, value string) error { return ValidateHeaderValueResult(name, value).Error() @@ -257,8 +265,12 @@ func ValidateHeaderValueResult(name, value string) ValidationResult { return ValidationResult{} } - if len(value) > 1024 { - return ValidationFailure(fmt.Errorf("header %s: value too long (max 1024 characters)", name)) + maxLen := maxHeaderValueLen + if strings.HasPrefix(value, EncryptedHeaderValuePrefix) { + maxLen = maxEncryptedHeaderValueLen + } + if len(value) > maxLen { + return ValidationFailure(fmt.Errorf("header %s: value too long (max %d characters)", name, maxLen)) } // Basic character validation - printable ASCII. We're stricter than the spec here - no UTF-8 for now diff --git a/livekit/sip_validation_test.go b/livekit/sip_validation_test.go index a1a1d8f19..7548ce277 100644 --- a/livekit/sip_validation_test.go +++ b/livekit/sip_validation_test.go @@ -100,6 +100,7 @@ var ValidHeaderValues = []string{ "Header with unicode 世界", // Unicode "Header with unicode émojis 🎉", // Unicode with emojis strings.Repeat("a", 1024), // max length + EncryptedHeaderValuePrefix + strings.Repeat("a", 8192-len(EncryptedHeaderValuePrefix)), // encrypted max length } // Note: These restrictions are NOT in RFC 3261 but are applied for security/performance @@ -111,6 +112,7 @@ var InvalidHeaderValues = []string{ "Header with\x1Funit separator", // control character "Header with\x7Fdelete", // delete character strings.Repeat("a", 1025), // too long + EncryptedHeaderValuePrefix + strings.Repeat("a", 8193-len(EncryptedHeaderValuePrefix)), // encrypted too long } // testCaseName truncates a test case name to maxLen and adds dots with total size