From a722110fc18a97a16c0534d0b0321b41dec63789 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2026 14:00:22 -0700 Subject: [PATCH 1/2] Adding name-addr validation --- livekit/sip_validation.go | 18 +++++++--- livekit/sip_validation_test.go | 63 ++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/livekit/sip_validation.go b/livekit/sip_validation.go index faefbd27d..a30df1c92 100644 --- a/livekit/sip_validation.go +++ b/livekit/sip_validation.go @@ -209,6 +209,13 @@ var nameAddrHeaders = map[string]bool{ "record-route": true, "reply-to": true, "p-asserted-identity": true, // RFC 3325 Section 9.1 + "referred-by": true, // RFC 3892 Section 3 +} + +var softFailureReporter func(err error) + +func SetSoftFailureReporter(reporter func(err error)) { + softFailureReporter = reporter } // ValidateHeaderName validates a SIP header name per RFC 3261 Section 25.1 @@ -253,10 +260,13 @@ func ValidateHeaderValue(name, value string) error { // Convert to lowercase for case-insensitive comparison lowerName := strings.ToLower(name) - if _, exists := nameAddrHeaders[lowerName]; exists && false { - // TODO: Disabled since all supported headers are forbidden, re-enable when we allow some + if _, exists := nameAddrHeaders[lowerName]; exists { if err := validateNameAddrHeader(value); err != nil { - return fmt.Errorf("header %s: value: %w", name, err) + err = fmt.Errorf("header %s: value: %w", name, err) + // For now do not actually error out on header values, just note failure. + if cb := softFailureReporter; cb != nil { + cb(err) + } } } @@ -315,7 +325,7 @@ func validateNameAddrHeader(value string) error { } } else { // This is a bare URI, and should comply with addr-spec, no special characters - if strings.ContainsAny(value, ";,? ") { + if strings.ContainsAny(value, ",? ") { return errors.New("bare URI with special characters") } } diff --git a/livekit/sip_validation_test.go b/livekit/sip_validation_test.go index 89e904873..266b5409f 100644 --- a/livekit/sip_validation_test.go +++ b/livekit/sip_validation_test.go @@ -125,27 +125,47 @@ func testCaseName(name string, maxLen int, index int) string { // ValidNameAddrHeaders contains valid Name-addr format headers with parameters var ValidNameAddrHeaders = []string{ - `"Alice Johnson" `, - `"Alice \"Ace\" Johnson's device\\" `, + // addr-spec schemes (bare) + `sip:u4@exmaple.com`, + `sips:u5@exmaple.com`, + `tel:+1-555-123-4567`, + + // bare addr-spec + header params (RFC 3261 §25.1 *( SEMI to-param )) + `sip:user@host;tag=abc`, + `sip:user@host;tag=abc;x-custom=val`, + `sip:r@host;cid="2UWQFN309shb3@ref.example"`, // quoted header param value + + // bracketed addr-spec (no display name) + ``, + ``, + ``, + ``, // SIP URI with transport + ``, // SIP URI with flag param + ``, // SIP URI with port + ``, // 2 uri-params + ``, // IPv6 + port + ``, // uri-header + ``, // 2 uri-headers + ``, // uri-param + uri-header + ``, // 2 uri-params + 2 uri-headers + + // bracketed addr-spec + header params after > + `;tag=abc`, + `;tag=abc;x-custom=val`, + `;tag=abc`, + `;tag=abc`, + `;tag=abc`, + `;tag=abc`, + `;tag=abc`, + `;tag=abc;x-custom=val`, + + // name-addr (display name + bracketed URI) + `Alice `, + `"Alice Johnson" `, `Alice Johnson `, - `sip:u4@example.com`, // basic SIP URI (no brackets needed) - `sips:u5@example.com`, // secure SIP URI (no brackets needed) - `tel:+1-555-123-4567`, // TEL URI (no brackets needed) - ``, // basic SIP URI with brackets - ``, // secure SIP URI with brackets - ``, // TEL URI with brackets - `Alice `, // display name + SIP URI - `"Alice Johnson" `, // quoted display name - ``, // SIP URI with transport - ``, // SIP URI with flag param - ``, // SIP URI with port - ``, // SIP URI with multiple params - `Alice `, // display name + params - `"Alice \"Ace\"" `, // quoted display - ``, // IPv6 with params - `;expires=60`, // SIPS URI with expires parameter - `Alice `, // display name + params - `"Alice & Bob" `, // display name with & symbol + `"Alice \"Ace\" Johnson's device\\" `, // quoted + escapes + `"Alice & Bob" `, // special char in quoted display + `Alice ;tag=abc`, } // InvalidNameAddrHeaders contains invalid Name-addr format headers @@ -163,7 +183,8 @@ var InvalidNameAddrHeaders = []string{ `Alice sip:u13@example.com`, // display name without brackets `Alice sips:u14@example.com`, // display name without brackets `Alice & Bob `, // display name with & symbol - `sip:u16@example.com;transport=tcp`, // special chars without brackets + `a-value`, // bare token, not a URI + `sip:user@host?X-Custom=val`, // uri-header in bare addr-spec (RFC 3261 §20) `sip:u17@example.com,transport=tcp`, // comma without brackets `sip:u18@example.com?transport=tcp`, // question mark without brackets ``, // missing equals sign From 3bc65ded321cffcf33fc3a5792c807aaf5d6e8a0 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 29 Jun 2026 14:02:11 -0700 Subject: [PATCH 2/2] changeset --- .changeset/famous-jokes-enter.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/famous-jokes-enter.md diff --git a/.changeset/famous-jokes-enter.md b/.changeset/famous-jokes-enter.md new file mode 100644 index 000000000..e1f764bd5 --- /dev/null +++ b/.changeset/famous-jokes-enter.md @@ -0,0 +1,5 @@ +--- +"github.com/livekit/protocol": patch +--- + +Enabling soft fail for sip validation