This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

Log a fastjson bug once

Fastjson uses whitelisting as a defense against deserialization holes, so while bugs are constantly creating new deserialization Gadgets classes, it’s possible to bypass the whitelisting defense even with autoType turned off, creating remote command execution vulnerabilities. According to the study, this vulnerability has a low utilization threshold and can bypass the autoType restriction with a large risk impact. Aliyun emergency Response Center reminded Fastjson users to take security measures to prevent vulnerability attacks as soon as possible.

But in the process of upgrading, there was a problem with one project. The problem is that Javabeans that use uppercase letters for attribute names have problems using this method.

//parseObject(String text, Class<T> clazz) 
Input input = JSONObject.parseObject(request.getData().toJSONString(), Input.class);
Copy the code

In the above code, the output input is null.

Two different versions of FastJSON are handled differently in the Fastjson DefaultJSONParser class.

1.2.12

public <T> T parseObject(Type type, Object fieldName) {
    int token = this.lexer.token();
    if (token == 8) {
        this.lexer.nextToken();
        return null;
    } else {
        if (token == 4) {
            if (type == byte[].class) {
                byte[] bytes = this.lexer.bytesValue();
                this.lexer.nextToken();
                return bytes;
            }

            if (type == char[].class) {
                String strVal = this.lexer.stringVal();
                this.lexer.nextToken();
                return strVal.toCharArray();
            }
        }

        ObjectDeserializer derializer = this.config.getDeserializer(type);

        try {
            // This is different
            return derializer.deserialze(this, type, fieldName);
        } catch (JSONException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw newJSONException(var7.getMessage(), var7); }}}Copy the code

As you can see from debugging, property assignments in version 1.2.12 are made using the property’s set method.

1.2.70 version

public <T> T parseObject(Type type, Object fieldName) {
    int token = this.lexer.token();
    if (token == 8) {
        this.lexer.nextToken();
        return null;
    } else {
        if (token == 4) {
            if (type == byte[].class) {
                byte[] bytes = this.lexer.bytesValue();
                this.lexer.nextToken();
                return bytes;
            }

            if (type == char[].class) {
                String strVal = this.lexer.stringVal();
                this.lexer.nextToken();
                return strVal.toCharArray();
            }
        }

        ObjectDeserializer deserializer = this.config.getDeserializer(type);

        try {
            if (deserializer.getClass() == JavaBeanDeserializer.class) {
                if (this.lexer.token() ! =12 && this.lexer.token() ! =14) {
                    throw new JSONException("syntax error,except start with { or [,but actually start with " + this.lexer.tokenName());
                } else {
                // After the update, go here
                    return ((JavaBeanDeserializer)deserializer).deserialze(this, type, fieldName, 0); }}else {
            // The original version went here
                return deserializer.deserialze(this, type, fieldName); }}catch (JSONException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw newJSONException(var7.getMessage(), var7); }}}Copy the code

1.2.70 is parsed in this way.

Finally, we found that we could use @jsonfield (name = “AAA001”) annotation to solve this problem. We can also use the uppercase input parameter to annotate the input class.

@JSONField(name = "AAA001)
private String AAA001; 1 / / attributes
Copy the code

The @jsonField (name = “AAA001”) annotation still doesn’t work on attributes because of the Lombok plugin. This can be done by displaying the get method that declares attributes.

    @JSONField(name = "AAA001")
    public String getAAA001(a) {
        return AAA001;
    }
Copy the code