
Fastjson again! This guy again! Experienced at least 2 + such scenes. I don't know which immortal this guy offended and was often "black". What did fastjson do wrong? Why are vulnerabilities frequently revealed? But as a technologist (interest enthusiast), I am more concerned about why it is frequently broken? The other Gson didn't. By consulting the release note and part of the source code of fastjson, it is found that this phenomenon is related to an AutoType feature in fastjson.
There are three popular class libraries for Java processing Json data, Gson(google maintenance), Jackson, and today's
Protagonist Fastjson.
Fastjson is an open source JSON related java library of Alibaba. Address: https://github.com/alibaba/fastjson , fastjson can convert Java objects into JSON form, and can also be used to convert JSON into Java objects. It has high efficiency and is widely used in web services and android. Its JSONString() method can convert Java objects into JSON format. Similarly, it can convert JSON data into Java objects through parseObject method. Alibaba's open source JSON parsing library is a powerful one, which is usually used to convert Java beans and JSON strings.
This time, the Ministry of industry and information technology reported that there were loopholes in the company's system, which led to the company's business lines upgrading the fastjson version to prevent system security problems. After viewing some business packages, it is found that different versions of fastjson are currently used, but they are all in 1.2.0 68. 2020 is an extraordinary year. The fastjson component library frequently exposes security vulnerabilities. This vulnerability can bypass the autoType switch to deserialize remote code execution and obtain server access.
From v1.0 released in July 2019 2.59 v1.59 until June 2020 2.71. In the upgrade of each version, there is an upgrade of AutoType, involving 13 official versions. The version history related to AutoType in fastjson can be referred to as follows:
1.2.59 Publish, enhance AutoType Security when opening fastjson 1.2.60 Release, added AutoType Blacklist, fix denial of service security issues fastjson 1.2.61 Publish, add AutoType Security blacklist fastjson 1.2.62 Publish, add AutoType Blacklists, enhanced date deserialization, and JSONPath fastjson 1.2.66 release, Bug Repair safety reinforcement, and do safety reinforcement, supplement AutoType blacklist fastjson 1.2.67 release, Bug Repair safety reinforcement and supplement AutoType blacklist fastjson 1.2.68 Release, support GEOJSON,Added AutoType blacklist 1.2.69 Release and repair newly found high risk AutoType Switch bypasses security vulnerabilities and adds AutoType blacklist 1.2.70 Release, improve compatibility and supplement AutoType blacklist 1.2.71 Release, supplement the security blacklist, no new utilization, preventive supplement
About 1.2 The vulnerability in version 68 is mainly exploited by exploiting exceptions and rewriting the getMessage method. In fact, the most widely used interface is autoclosable, which bypasses checkAutoType. Most of the online analysis is also carried out in this way. Because the conditions required by the payload composed of autoclosable may not be so complex. A previous article said 1.2 69 has fixed the anomaly attack vulnerability, but it does not seem to have been tested.
However, as of November 2020, v1 In version 2.75, the exception class is still not handled, so there is still a vulnerability. The exploitation conditions of the vulnerability are as follows:
1. The dangerous class must inherit any exception class in the "system white list"
2. The dangerous method in the dangerous class must be a constructor or setter method, and controllable parameters are the best.
With fastjson1 2.68 as an example, the main reason is that fastjson added the checkAutoType method to avoid the vulnerability caused by the user's deserialization with its AutoType mechanism again. The flag of the AutoType mechanism is the tag "@ type". The purpose of the checkAutoType method is not to let the user use AutoType unless the user starts AutoType himself. However, during the implementation of the checkAutoType method, I still couldn't help using it secretly (the flag is that the "@ type" flag is resolved), but the restriction is strengthened. During the code audit, I found that on COM alibaba. fastjson. parser. Parserconfig line 1326
clazz = TypeUtils.getClassFromMapping(typeName);
The typeName variable is the string containing the class name in the serialized JSON format data entered by the user, such as {"@ type","com.demo.test"} JSON data, and its typeName is com demo. test. This line of code means to try to get the class mentioned in JSON from the TypeUtils class. In the static method of TypeUtils, the addBaseClassMappings function is executed. The function code is as follows (note that it contains the autoclosable interface):
private static void addBaseClassMappings(){ mappings.put("byte", byte.class); mappings.put("short", short.class); mappings.put("int", int.class); mappings.put("long", long.class); mappings.put("float", float.class); mappings.put("double", double.class); mappings.put("boolean", boolean.class); mappings.put("char", char.class); mappings.put("[byte", byte[].class); mappings.put("[short", short[].class); mappings.put("[int", int[].class); mappings.put("[long", long[].class); mappings.put("[float", float[].class); mappings.put("[double", double[].class); mappings.put("[boolean", boolean[].class); mappings.put("[char", char[].class); mappings.put("[B", byte[].class); mappings.put("[S", short[].class); mappings.put("[I", int[].class); mappings.put("[J", long[].class); mappings.put("[F", float[].class); mappings.put("[D", double[].class); mappings.put("[C", char[].class); mappings.put("[Z", boolean[].class); Class<?>[] classes = new Class[]{ Object.class, java.lang.Cloneable.class, loadClass("java.lang.AutoCloseable"), java.lang.Exception.class, java.lang.RuntimeException.class, java.lang.IllegalAccessError.class, java.lang.IllegalAccessException.class, java.lang.IllegalArgumentException.class, java.lang.IllegalMonitorStateException.class, java.lang.IllegalStateException.class, java.lang.IllegalThreadStateException.class, java.lang.IndexOutOfBoundsException.class, java.lang.InstantiationError.class, java.lang.InstantiationException.class, java.lang.InternalError.class, java.lang.InterruptedException.class, java.lang.LinkageError.class, java.lang.NegativeArraySizeException.class, java.lang.NoClassDefFoundError.class, java.lang.NoSuchFieldError.class, java.lang.NoSuchFieldException.class, java.lang.NoSuchMethodError.class, java.lang.NoSuchMethodException.class, java.lang.NullPointerException.class, java.lang.NumberFormatException.class, java.lang.OutOfMemoryError.class, java.lang.SecurityException.class, java.lang.StackOverflowError.class, java.lang.StringIndexOutOfBoundsException.class, java.lang.TypeNotPresentException.class, java.lang.VerifyError.class, java.lang.StackTraceElement.class, java.util.HashMap.class, java.util.Hashtable.class, java.util.TreeMap.class, java.util.IdentityHashMap.class, java.util.WeakHashMap.class, java.util.LinkedHashMap.class, java.util.HashSet.class, java.util.LinkedHashSet.class, java.util.TreeSet.class, java.util.ArrayList.class, java.util.concurrent.TimeUnit.class, java.util.concurrent.ConcurrentHashMap.class, java.util.concurrent.atomic.AtomicInteger.class, java.util.concurrent.atomic.AtomicLong.class, java.util.Collections.EMPTY_MAP.getClass(), java.lang.Boolean.class, java.lang.Character.class, java.lang.Byte.class, java.lang.Short.class, java.lang.Integer.class, java.lang.Long.class, java.lang.Float.class, java.lang.Double.class, java.lang.Number.class, java.lang.String.class, java.math.BigDecimal.class, java.math.BigInteger.class, java.util.BitSet.class, java.util.Calendar.class, java.util.Date.class, java.util.Locale.class, java.util.UUID.class, java.sql.Time.class, java.sql.Date.class, java.sql.Timestamp.class, java.text.SimpleDateFormat.class, com.alibaba.fastjson.JSONObject.class, com.alibaba.fastjson.JSONPObject.class, com.alibaba.fastjson.JSONArray.class, }; for(Class clazz : classes){ if(clazz == null){ continue; } mappings.put(clazz.getName(), clazz); } }
It can be found that the system adds these classes to the mappings. The method mentioned earlier is obvious, that is, try to obtain the typeName value in the TypeUtils class. If it is not obtained, then clazz is null. If expectClass is also null at this time, an exception will be triggered to tell the user that AutoType is unavailable. Under normal circumstances, AutoType is prohibited. However, there is another case. If clazz is not empty, it is possible to bypass the restriction. The key to bypass is TypeUtils The classes contained in mappings are equivalent to the "white list of the system".
More detailed:
1. fastjson will first look for the key with "@ type" in JSON format from left to right. If it exists, check whether the value corresponding to the key (i.e. typeName) is in the "system whitelist" and user-defined whitelist through the checkAutoType method. Of course, the system has its own blacklist, and typeName cannot be in the blacklist.
The following is 1.2 68 blacklist set by the system:
if (expectClass == null) { expectClassFlag = false; } else { if (expectClass == Object.class || expectClass == Serializable.class || expectClass == Cloneable.class || expectClass == Closeable.class || expectClass == EventListener.class || expectClass == Iterable.class || expectClass == Collection.class ) { expectClassFlag = false; } else { expectClassFlag = true; } }
2. After determining that the typeName is not on the blacklist but on the whitelist, the typeName will be assigned to expectClass. expectClass is a good thing, which is equivalent to a powerful pass. It will allow the sons of expectClass (implementation class or subclass) to pass directly without passing the system whitelist check. 1.2. 68 loopholes also arise from this "pass".
The characteristics of the three Json frameworks are briefly described as follows:
- Fastjson
1,Fast speed fastjson Relative to others JSON The library is characterized by fast from 2011 fastjson Release 1.1.x After version, its performance has been higher than other type libraries 2,Easy to use fastjson of API Very concise. 3,Widely used fastjson It is widely used in Alibaba and deployed on tens of thousands of servers, fastjson It is widely accepted in the industry.
- Jackson
1,Easy to use - jackson API Provides a high-level look and feel to simplify common use cases. 2,No mapping is required - API Provides a default mapping for most object serialization. 3,High performance - Fast, low memory consumption, suitable for large object charts or systems. 4,clean JSON - jackson Create a clean and compact JSON As a result, it is easy to read. 5,Not dependent - Libraries do not require any other libraries except JDK.
- Gson
1,Output light and easy to read JSON. 2,Supports arbitrarily complex objects. 3,Allows you to customize the presentation of objects. 4,Allow pre-existing immutable objects to be converted to JSON Or vice versa. 5,Provide a mechanism that will Java Object to JSON Or vice versa toString()As simple as a constructor (factory method).
In contrast, other json frameworks, such as Gson and Jackson, have much fewer vulnerabilities and fewer high-risk vulnerabilities. In addition, the other two frameworks are also making efforts to improve, and each has its own advantages. In the medium and long term, if the fastjson vulnerability can not be repaired or avoided, isn't Gson a more cost-effective choice?