#14971·kong

validate_utf8 incorrectly accepts invalid 2-byte UTF-8 sequences containing ASCII characters

Author: pritesh-4Created Aug 11, 2026Updated Aug 11, 2026

Is there an existing issue for this?

  • I have searched the existing issues

Kong version ($ kong version)

Kong 3.10.0

Current Behavior

The utility function validate_utf8 in kong.tools.string is used across various schema definition files (e.g. tag validation, upstream names, targets, workspaces, etc.) to ensure that user inputs are strictly valid UTF-8 sequences.

Due to a typographical error in the byte range boundaries of 2-byte UTF-8 sequences, the function accepts malformed 2-byte sequences where the second byte (the continuation byte) is an ASCII punctuation or control character in the decimal range 123..127 (such as {, |, }, ~, DEL).

In Lua, string escape sequences in the form of \ddd represent decimal byte values (unlike other languages like Bash/Python where they represent octal values). For example, \123 evaluates to the decimal value 123 (which is ASCII {), while \128 evaluates to decimal 128 (0x80).

According to Table 3-7 of the Unicode Standard (which the codebase explicitly references in the function comments), a valid 2-byte UTF-8 sequence consists of:

A leading byte in the range 0xC2..0xDF (decimal 194..223). A continuation byte in the range 0x80..0xBF (decimal 128..191). However, in

kong/tools/string.lua#L254 , the continuation byte range is defined using [\123-\191]:

-- Numbers taken from table 3-7 in www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf -- find-based solution inspired by http://notebook.kulchenko.com/programming/fixing-malformed-utf8-in-lua function _M.validate_utf8(val) local str = tostring(val) local i, len = 1, #str while i <= len do if i == find(str, "[%z\1-\127]", i) then i = i + 1 elseif i == find(str, "[\194-\223][\123-\191]", i) then i = i + 2 -- <--- BUG HERE

Expected Behavior

The validation should fail and return false, because 0x7B (decimal 123) is outside the valid UTF-8 continuation byte range (0x80..0xBF / 128..191).

Steps To Reproduce

You can reproduce this behavior directly in a Lua interactive environment or via a test script: local validate_utf8 = require("kong.tools.string").validate_utf8

-- 0xC2 (194) is a valid lead byte for 2-byte sequences. -- 0x7B (123) is ASCII '{' and is NOT a valid continuation byte. local invalid_sequence = string.char(194, 123)

print("Is valid UTF-8:", validate_utf8(invalid_sequence))

Anything else?

No response