Live data from Hacker News

How fast can you validate UTF-8 strings in JavaScript?

lemire.me

11–18 of 18 posts

Re: How fast can you validate UTF-8 strings in JavaScript?

#11

The article claims that accepting 'invalid' UTF-8 can be a security risk. Can someone explain how?

I'm not sure. However, there are some rendering engines that will completely choke on certain data. For a while, iOS would crash every time you opened iMessage if someone sent you an invalid sequence. Perhaps invalid UTF-8 could cause this? If so it would make an effective DoS attack vector.

Re: How fast can you validate UTF-8 strings in JavaScript?

#12

Earlier quoted context omitted.

Wouldn’t "visually identical” tokens still be valid utf8?

It depends on the meaning of 'valid UTF-8'. They could be 'UTF-8 that is invalid for my application', but still be 'strings that are valid under the UTF-8 specification'.

There is no such thing as "UTF-8 that is invalid for my application". Any properly encoded sequence of UTF-8 codepoints is valid UTF-8. Your application may have constraints on the codepoints that it should accept, but that does not suddenly make them improperly encoded. Using visually-similar lookalikes does not make a UTF-8 string invalid.

Re: How fast can you validate UTF-8 strings in JavaScript?

#13

The article claims that accepting 'invalid' UTF-8 can be a security risk. Can someone explain how?

Assuming that data is valid UTF-8 can result in you passing this data to other systems that make the same assumption. If nobody validates the data, it can cause unintended behavior or crashes. If someone downstream validates the data and returns you an error, it may be an error you didn't expect, and you may not handle it properly.

Re: How fast can you validate UTF-8 strings in JavaScript?

#14

The article claims that accepting 'invalid' UTF-8 can be a security risk. Can someone explain how?

For necessary performance reasons, a lot of code does not ensure that its input is valid UTF-8, and simply leaves that burden to the programmer. Strings are often passed through many, many layers of various types of processing, and it would slow code down significantly if each step in this process needed to validate the entire string all over again, so it's typical to expect that the string is validated once at the beginning, and then passed through various routines that each blindly assume their input is valid UTF-8 and guarantee to return valid UTF-8 as well if that assumption is true.

If you skip this initial validation, you open yourself to security problems caused by differences in the undefined behavior of these various routines that are assuming valid input. As an example, imagine if your code for escaping HTML saw an invalid byte sequence immediately before a "<" and failed to escape it because of that, but then the HTML parser you pass the result to treats the invalid byte sequence differently and successfully sees and parses the "<" that should have been escaped.

Re: How fast can you validate UTF-8 strings in JavaScript?

#15

Earlier quoted context omitted.

It depends on the meaning of 'valid UTF-8'. They could be 'UTF-8 that is invalid for my application', but still be 'strings that are valid under the UTF-8 specification'.

There is no such thing as "UTF-8 that is invalid for my application". Any properly encoded sequence of UTF-8 codepoints is valid UTF-8. Your application may have constraints on the codepoints that it should accept, but that does not suddenly make them improperly encoded. Using visually-similar lookalikes does not make a UTF-8 string invalid.

> There is no such thing as "UTF-8 that is invalid for my application".

In fact, yes there is! Your application may vary. :)

Re: How fast can you validate UTF-8 strings in JavaScript?

#17

The article claims that accepting 'invalid' UTF-8 can be a security risk. Can someone explain how?

I would like to see some real examples too, but I think a pretty common thing is bypassing URL deny-lists with different representations of the same string, or any kind of ACL

e.g. the developer might either deny or allow /admin/, or /admin/.*

But if a given Unicode string [1] has two representations, then that check may not work as intended for one of them.

---

UTF-8 represents code points with 1-4 bytes, which are roughly similar to base 64 digits (because a continuation byte is 10xx_xxxx, it has 6 bits of freedom)

This opens up the possibility of "overlong encodings", which a UTF-8 validator must reject.

That is, you can do the equivalent of representing a number as "09" instead of "9" -- that's an overlong encoding. A decoder may understand "09" and "9" as both being the digit 9, but it's a different sequence of bytes.

So a naive decoding algorithm can accept a spelling of "admin" as 6, 7, 8, ... 20 bytes, not 5. There are many overlong encodings!

The only valid UTF-8 spelling has 5 bytes, but decoders that don't validate will "naturally" accept more (in fact I think I even wrote one of these :-/ )

In summary, if you don't do UTF-8 validation, then one layer doesn't reject the invalid representation, and another layer may decode it into a valid Unicode string.

Also, some regex engines work on UTF-8 encoded bytes, and some work on arrays of code points.

---

Again I'd be interested in more real examples.

[1] A sequence of "Unicode scalars" -- code points not in the surrogate range

Re: How fast can you validate UTF-8 strings in JavaScript?

#18

Earlier quoted context omitted.

There is no such thing as "UTF-8 that is invalid for my application". Any properly encoded sequence of UTF-8 codepoints is valid UTF-8. Your application may have constraints on the codepoints that it should accept, but that does not suddenly make them improperly encoded. Using visually-similar lookalikes does not make a UTF-8 string invalid.

> There is no such thing as "UTF-8 that is invalid for my application". In fact, yes there is! Your application may vary. :)

UTF-8 doesn't vary, it's just an encoding.
Post reply on HN