From 97347fb272a5692d6bca8ce4d3e33a317c5e1cdf Mon Sep 17 00:00:00 2001 From: neeraj netrakar Date: Fri, 16 Oct 2026 14:09:35 +0530 Subject: [PATCH] Avoid out-of-bounds table read in balsa URI char validators HasInvalidPathChar and HasInvalidQueryChar iterated the value with a signed char and used it directly to index a 256-entry lookup table, so any byte >= 0x80 indexed the table out of bounds. The sibling validators in this file already cast to uint8_t before indexing; do the same here. Add regression cases covering high-bit bytes. --- quiche/balsa/header_properties.cc | 4 ++-- quiche/balsa/header_properties_test.cc | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/quiche/balsa/header_properties.cc b/quiche/balsa/header_properties.cc index 57ffbc10e..2f2aecdcc 100644 --- a/quiche/balsa/header_properties.cc +++ b/quiche/balsa/header_properties.cc @@ -241,7 +241,7 @@ bool HasInvalidHeaderChars(absl::string_view value) { bool HasInvalidPathChar(absl::string_view value) { static constexpr std::array invalidCharTable = buildInvalidPathCharLookupTable(); - for (const char c : value) { + for (const uint8_t c : value) { if (invalidCharTable[c]) { return true; } @@ -252,7 +252,7 @@ bool HasInvalidPathChar(absl::string_view value) { bool HasInvalidQueryChar(absl::string_view value) { static constexpr std::array invalidCharTable = buildInvalidQueryCharLookupTable(); - for (const char c : value) { + for (const uint8_t c : value) { if (invalidCharTable[c]) { return true; } diff --git a/quiche/balsa/header_properties_test.cc b/quiche/balsa/header_properties_test.cc index f4e749a84..aee18e684 100644 --- a/quiche/balsa/header_properties_test.cc +++ b/quiche/balsa/header_properties_test.cc @@ -122,6 +122,11 @@ TEST(HeaderPropertiesTest, HasInvalidPathChar) { EXPECT_TRUE(HasInvalidPathChar("/path\rwith\tother\nwhitespace")); EXPECT_TRUE(HasInvalidPathChar("/backtick`")); EXPECT_TRUE(HasInvalidPathChar("/anglealso/bad")); + // Bytes >= 0x80 are not valid path characters and must be rejected + // without indexing the lookup table out of bounds. + EXPECT_TRUE(HasInvalidPathChar("/caf\xc3\xa9")); + EXPECT_TRUE(HasInvalidPathChar(std::string(1, '\x80'))); + EXPECT_TRUE(HasInvalidPathChar(std::string(1, '\xff'))); } TEST(HeaderPropertiesTest, HasInvalidQueryChar) { @@ -143,6 +148,11 @@ TEST(HeaderPropertiesTest, HasInvalidQueryChar) { EXPECT_TRUE(HasInvalidQueryChar("query with spaces")); EXPECT_TRUE(HasInvalidQueryChar("query\rwith\tother\nwhitespace")); EXPECT_TRUE(HasInvalidQueryChar("query_with_anglealso_bad")); + // Bytes >= 0x80 are not valid query characters and must be rejected + // without indexing the lookup table out of bounds. + EXPECT_TRUE(HasInvalidQueryChar("caf\xc3\xa9")); + EXPECT_TRUE(HasInvalidQueryChar(std::string(1, '\x80'))); + EXPECT_TRUE(HasInvalidQueryChar(std::string(1, '\xff'))); } TEST(HeaderPropertiesTest, IsValidTokenVsHasInvalidHeaderChars) {