Fastjson just fixed a bug which might cause out of memory issue

Summary

Fastjson recently patched an OutOfMemory vulnerability stemming from improper handling of `\x` escape sequences during JSON string parsing. The bug, located in `JSONLexerBase#scanString`, occurred when `\x` was the final character in a string, causing the parser to read past the buffer boundary without validation. This led to an infinite loop attempting to process an already consumed End-Of-Input marker, ultimately resulting in an OOM error. The fix introduces explicit hexadecimal character checks for the two characters following `\x`, throwing an exception for invalid sequences and preventing the erroneous read. Developers using Fastjson versions below 1.2.60 should upgrade immediately to mitigate this potential service-disrupting issue.

Fastjson just fixed a bug which might cause service down a few days ago. This bug is caused by some mishandling of special character \x which is an escaped character to indicate hexdecimal number. The impact of this bug would be big if the attacker constructs a malicious data which would cause the service down. 

The code which causes the issue is in com.alibaba.fastjson.parser.JSONLexerBase#scanString, when a JSON string is passed in, fastjson would parse the string character by character, when it finds the \x, it would try to process the following two characters automatically and treat them as hexdecimal character.

case 'x':
    char x1 = ch = next();
    char x2 = ch = next();

    int x_val = digits[x1] * 16 + digits[x2];
    char x_char = (char) x_val;
    putChar(x_char);
    break;

However, it might encounter problem if the \x is the last character in the string, since fastjson doesn't do any boundary check and it will always try to read the next two characters and would eventually read EOF(\u001A). Thereafter it continues to read and try to find EOF, but since EOF has been processed already, it will again try to find EOF but never finds it anymore until out of memory occurs.

if (ch == EOI) {
    if (!isEOF()) {
        putChar((char) EOI);
        continue;
    }
    throw new JSONException("unclosed string : " + ch);
}

The fix made is basically adding some extra check after reading \x.

case 'x':
    char x1 = next();
    char x2 = next();

    boolean hex1 = (x1 >= '0' && x1 <= '9')
            || (x1 >= 'a' && x1 <= 'f')
            || (x1 >= 'A' && x1 <= 'F');
    boolean hex2 = (x2 >= '0' && x2 <= '9')
            || (x2 >= 'a' && x2 <= 'f')
            || (x2 >= 'A' && x2 <= 'F');
    if (!hex1 || !hex2) {
        throw new JSONException("invalid escape character \\x" + x1 + x2);
    }

    char x_char = (char) (digits[x1] * 16 + digits[x2]);
    putChar(x_char);
    break;

All versions below 1.2.60 are affected, please upgrade to the latest version if you are still using one of the impacted versions.

BUG ALIBABA NEWS FASTJSON

  RELATED

  COMMENTS

0

No comment for this article.