From 701c4da23913b82c62e71ade7c80d178f22d7b21 Mon Sep 17 00:00:00 2001 From: tonghuaroot Date: Wed, 27 May 2026 08:58:05 +0800 Subject: [PATCH] x/text/language: count '_' alongside '-' in ParseAcceptLanguage guard The BCP 47 scanner aliases '_' to '-' in scanner.init (internal/language/parse.go), so an attacker can replace every '-' with '_' to bypass the 1000-dash guard added in CL 442235 (the CVE-2022-32149 fix) and re-trigger the O(N^2) gobble path on attacker-controlled Accept-Language input. Count both separators in the guard. Fixes golang/go#79684 --- language/parse.go | 4 +++- language/parse_test.go | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/language/parse.go b/language/parse.go index 053336e2..65b53b91 100644 --- a/language/parse.go +++ b/language/parse.go @@ -166,7 +166,9 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { } }() - if strings.Count(s, "-") > 1000 { + // The BCP 47 scanner aliases '_' to '-' in scanner.init + // (internal/language/parse.go); the guard must count both. + if strings.Count(s, "-")+strings.Count(s, "_") > 1000 { return nil, nil, errTagListTooLarge } diff --git a/language/parse_test.go b/language/parse_test.go index 0eee033e..189b24f1 100644 --- a/language/parse_test.go +++ b/language/parse_test.go @@ -407,3 +407,18 @@ func TestParseAcceptLanguageTooBig(t *testing.T) { t.Errorf("ParseAcceptLanguage() unexpected error: got %v, want %v", err, errTagListTooLarge) } } + +func TestParseAcceptLanguageUnderscoreGuard(t *testing.T) { + // Build a payload that would trigger the quadratic path with + // '_' but is blocked by the dash-count guard. Verify the guard + // now also counts '_'. + parts := make([]string, 0, 1002) + parts = append(parts, "en") + for i := 0; i < 1001; i++ { + parts = append(parts, "abcdefghi") + } + s := strings.Join(parts, "_") + if _, _, err := ParseAcceptLanguage(s); err != errTagListTooLarge { + t.Errorf("ParseAcceptLanguage with 1001 '_' separators: got err=%v, want errTagListTooLarge", err) + } +}