spinjar.com.fasterxml.jackson.databind.jsontype.DefaultBaseTypeLimitingValidator Maven / Gradle / Ivy
package com.fasterxml.jackson.databind.jsontype;
import java.util.HashSet;
import java.util.Set;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
/**
* {@link PolymorphicTypeValidator} that will only allow polymorphic handling if
* the base type is NOT one of potential dangerous base types (see {@link #isUnsafeBaseType}
* for specific list of such base types). No further validation is performed on subtype.
*
* Note that when using potentially unsafe base type like {@link java.lang.Object} a custom
* implementation (or subtype with override) is needed. Most commonly subclasses would
* override both {@link #isUnsafeBaseType} and {@link #isSafeSubType}: former to allow
* all (or just more) base types, and latter to add actual validation of subtype.
*
* @since 2.11
*/
public class DefaultBaseTypeLimitingValidator
extends PolymorphicTypeValidator
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
@Override
public Validity validateBaseType(MapperConfig config, JavaType baseType)
{
// Immediately block potentially unsafe base types
if (isUnsafeBaseType(config, baseType)) {
return Validity.DENIED;
}
// otherwise indicate that type may be ok (so further calls are made --
// does not matter with base implementation but allows easier sub-classing)
return Validity.INDETERMINATE;
}
@Override
public Validity validateSubClassName(MapperConfig config,
JavaType baseType, String subClassName) {
// return INDETERMINATE just for easier sub-classing
return Validity.INDETERMINATE;
}
@Override
public Validity validateSubType(MapperConfig config, JavaType baseType,
JavaType subType)
{
return isSafeSubType(config, baseType, subType)
? Validity.ALLOWED
: Validity.DENIED;
}
/**
* Helper method called to determine if the given base type is known to be
* problematic regarding possible "gadget types".
* Currently includes following types:
*
* - {@link java.lang.Object}
* - {@link java.io.Closeable}
* - {@link java.io.Serializable}
* - {@link java.lang.AutoCloseable}
* - {@link java.lang.Cloneable}
* - {@link java.util.logging.Handler}
* - {@link javax.naming.Referenceable}
* - {@link javax.sql.DataSource}
*
* which are JDK-included super types of at least one gadget type (not necessarily
* included in JDK)
*
* @param config Current mapper configuration
* @param baseType Base type to test
*/
protected boolean isUnsafeBaseType(MapperConfig config, JavaType baseType)
{
return UnsafeBaseTypes.instance.isUnsafeBaseType(baseType.getRawClass());
}
/**
* Helper called to determine whether given actual subtype is considered safe
* to process: this will only be called if subtype was considered acceptable
* earlier.
*
* @param config Current mapper configuration
* @param baseType Base type of sub type (validated earlier)
* @param subType Sub type to test
*/
protected boolean isSafeSubType(MapperConfig config,
JavaType baseType, JavaType subType)
{
return true;
}
private final static class UnsafeBaseTypes {
public final static UnsafeBaseTypes instance = new UnsafeBaseTypes();
private final Set UNSAFE = new HashSet<>();
{
// first add names of types in `java.base`
UNSAFE.add(Object.class.getName());
UNSAFE.add(java.io.Closeable.class.getName());
UNSAFE.add(java.io.Serializable.class.getName());
UNSAFE.add(AutoCloseable.class.getName());
UNSAFE.add(Cloneable.class.getName());
// and then couple others typically included in JDK, but that we
// prefer not adding direct reference to
UNSAFE.add("java.util.logging.Handler");
UNSAFE.add("javax.naming.Referenceable");
UNSAFE.add("javax.sql.DataSource");
}
public boolean isUnsafeBaseType(Class rawBaseType)
{
return UNSAFE.contains(rawBaseType.getName());
}
}
}