diff --git a/pkg/server/locales/locales.go b/pkg/server/locales/locales.go index 2f43d0b6b..ccecc5ebf 100644 --- a/pkg/server/locales/locales.go +++ b/pkg/server/locales/locales.go @@ -1,6 +1,9 @@ package locales import ( + "errors" + "strings" + "golang.org/x/text/language" "k8s.io/klog/v2" ) @@ -25,6 +28,17 @@ func GetLocale(acceptLangHeader string) Localization { } func getPreferredLang(acceptLangHeader string) string { + // OCPBUGS-92015: In order to prevent the Quadratic-time DoS attack + // that is possible as documented by https://github.com/golang/go/issues/79684, + // return early with the fallback to english if there are more than 1000 underscore and hyphen + // characters in the Accept-Language header. + // This can be removed once we have updated the language dependency to a version + // that has fixed this issue. + if strings.Count(acceptLangHeader, "-")+strings.Count(acceptLangHeader, "_") > 1000 { + klog.V(5).Infof("Error parsing 'Accept-Language' header, falling back to English language: %v", errors.New("tag list exceeds max length")) + return language.English.String() + } + matcher := language.NewMatcher(supportedLangs) userPrefs, _, err := language.ParseAcceptLanguage(acceptLangHeader) if err != nil { diff --git a/pkg/server/locales/locales_test.go b/pkg/server/locales/locales_test.go index fa8c9d625..87839a467 100644 --- a/pkg/server/locales/locales_test.go +++ b/pkg/server/locales/locales_test.go @@ -2,6 +2,7 @@ package locales import ( "reflect" + "strings" "testing" ) @@ -51,6 +52,21 @@ func TestLocales(t *testing.T) { header: "cz;q=0.5, de;q=0.8", locale: locale_en, }, + { + name: "Test 'Accept-Language' request header with too many underscores, so defaults to English language", + header: strings.Repeat("_", 2000), + locale: locale_en, + }, + { + name: "Test 'Accept-Language' request header with too many hyphens, so defaults to English language", + header: strings.Repeat("-", 2000), + locale: locale_en, + }, + { + name: "Test 'Accept-Language' request header with too many underscores + hyphens, so defaults to English language", + header: strings.Repeat("_", 800) + strings.Repeat("-", 800), + locale: locale_en, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {