diff --git a/common/src/main/java/org/apache/drill/common/util/JacksonUtils.java b/common/src/main/java/org/apache/drill/common/util/JacksonUtils.java index e0cb0dee805..e3fdb32eb04 100644 --- a/common/src/main/java/org/apache/drill/common/util/JacksonUtils.java +++ b/common/src/main/java/org/apache/drill/common/util/JacksonUtils.java @@ -20,6 +20,8 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; /** * Utility class which contain methods for interacting with Jackson. @@ -50,7 +52,8 @@ public static ObjectMapper createObjectMapper(final JsonFactory factory) { * @return an {@link JsonMapper.Builder} instance */ public static JsonMapper.Builder createJsonMapperBuilder() { - return JsonMapper.builder(); + return JsonMapper.builder() + .polymorphicTypeValidator(createPolymorphicTypeValidator()); } /** @@ -59,6 +62,22 @@ public static JsonMapper.Builder createJsonMapperBuilder() { * @return an {@link JsonMapper.Builder} instance */ public static JsonMapper.Builder createJsonMapperBuilder(final JsonFactory factory) { - return JsonMapper.builder(factory); + return JsonMapper.builder(factory) + .polymorphicTypeValidator(createPolymorphicTypeValidator()); } + + // The more restrictive this validator is, the better for security. + private static PolymorphicTypeValidator createPolymorphicTypeValidator() { + return BasicPolymorphicTypeValidator.builder() + .allowIfSubType(Number.class) + .allowIfSubType(Boolean.class) + .allowIfSubType(String.class) + .allowIfSubType(byte[].class) + .allowIfSubType("java.time.") + .allowIfSubType("org.joda.time.") // Joda used by ColumnStatistics + .allowIfSubType("org.apache.drill.exec.") + .allowIfSubType("org.apache.drill.metastore.") + .build(); + } + } diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/DrillbitPluginRegistryContext.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/DrillbitPluginRegistryContext.java index 4565b55fa77..44e9bb98d00 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/DrillbitPluginRegistryContext.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/DrillbitPluginRegistryContext.java @@ -45,7 +45,7 @@ public DrillbitPluginRegistryContext(DrillbitContext drillbitContext) { // to handle HOCON format in the override file LogicalPlanPersistence persistence = new LogicalPlanPersistence(drillbitContext.getConfig(), drillbitContext.getClasspathScan(), - JacksonUtils.createObjectMapper(new HoconFactory())); + JacksonUtils.createJsonMapperBuilder(new HoconFactory()).build()); hoconMapper = persistence.getMapper(); } diff --git a/logical/src/main/java/org/apache/drill/common/config/LogicalPlanPersistence.java b/logical/src/main/java/org/apache/drill/common/config/LogicalPlanPersistence.java index 903b8f014f6..48548714967 100644 --- a/logical/src/main/java/org/apache/drill/common/config/LogicalPlanPersistence.java +++ b/logical/src/main/java/org/apache/drill/common/config/LogicalPlanPersistence.java @@ -65,9 +65,9 @@ public LogicalPlanPersistence(DrillConfig conf, ScanResult scanResult, ObjectMap mapper.setInjectableValues(injectables); mapper.registerModule(deserModule); mapper.enable(SerializationFeature.INDENT_OUTPUT); - mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, true); - mapper.configure(Feature.ALLOW_COMMENTS, true); + mapper.enable(Feature.ALLOW_UNQUOTED_FIELD_NAMES); + mapper.enable(JsonGenerator.Feature.QUOTE_FIELD_NAMES); + mapper.enable(Feature.ALLOW_COMMENTS); mapper.setFilterProvider(new SimpleFilterProvider().setFailOnUnknownId(false)); // For LogicalOperatorBase registerSubtypes(getSubTypes(scanResult, LogicalOperator.class)); @@ -92,7 +92,7 @@ private void registerSubtypes(Set> types) { * Scan for implementations of the given interface. * * @param classpathScan Drill configuration object used to find the packages to scan - * @return list of classes that implement the interface. + * @return set of classes that implement the interface. */ public static Set> getSubTypes(final ScanResult classpathScan, Class parent) { Set> subclasses = classpathScan.getImplementations(parent); diff --git a/metastore/metastore-api/src/main/java/org/apache/drill/metastore/statistics/ColumnStatistics.java b/metastore/metastore-api/src/main/java/org/apache/drill/metastore/statistics/ColumnStatistics.java index b909280a5e6..beb3e4eb2df 100644 --- a/metastore/metastore-api/src/main/java/org/apache/drill/metastore/statistics/ColumnStatistics.java +++ b/metastore/metastore-api/src/main/java/org/apache/drill/metastore/statistics/ColumnStatistics.java @@ -67,9 +67,10 @@ @JsonPropertyOrder({"statistics", "comparator"}) public class ColumnStatistics { - private static final ObjectMapper MAPPER = JacksonUtils.createJsonMapperBuilder() - .addModule(new JodaModule()) - .build(); + private static final ObjectMapper MAPPER = + JacksonUtils.createJsonMapperBuilder() + .addModule(new JodaModule()) + .build(); private static final ObjectWriter OBJECT_WRITER = MAPPER.writerFor(ColumnStatistics.class); diff --git a/pom.xml b/pom.xml index 229a50405f9..5568fa6d251 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ 5.11.0 0.12.1 1.3.1 - 2.18.3 + 2.18.9 3.1.12 3.29.2-GA 3.0.0