blob: 5ccb0fb7837e284c14ea6e9420daea10ca058a38 [file] [log] [blame]
package com.fasterxml.jackson.databind.interop;
import java.util.*;
import org.springframework.jacksontest.BogusApplicationContext;
import org.springframework.jacksontest.BogusPointcutAdvisor;
import org.springframework.jacksontest.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.mchange.v2.c3p0.jacksontest.ComboPooledDataSource;
/**
* Test case(s) to guard against handling of types that are illegal to handle
* due to security constraints.
*/
public class IllegalTypesCheckTest extends BaseMapTest
{
static class Bean1599 {
public int id;
public Object obj;
}
static class PolyWrapper {
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.WRAPPER_ARRAY)
public Object v;
}
static class Authentication1872 {
public List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
}
/*
/**********************************************************
/* Unit tests
/**********************************************************
*/
private final ObjectMapper MAPPER = objectMapper();
// // // Tests for [databind#1599]
public void testXalanTypes1599() throws Exception
{
final String clsName = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
final String JSON = aposToQuotes(
"{'id': 124,\n"
+" 'obj':[ '"+clsName+"',\n"
+" {\n"
+" 'transletBytecodes' : [ 'AAIAZQ==' ],\n"
+" 'transletName' : 'a.b',\n"
+" 'outputProperties' : { }\n"
+" }\n"
+" ]\n"
+"}"
);
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
try {
mapper.readValue(JSON, Bean1599.class);
fail("Should not pass");
} catch (JsonMappingException e) {
_verifySecurityException(e, clsName);
}
}
// // // Tests for [databind#1737]
public void testJDKTypes1737() throws Exception
{
_testIllegalType(java.util.logging.FileHandler.class);
_testIllegalType(java.rmi.server.UnicastRemoteObject.class);
}
// // // Tests for [databind#1855]
public void testJDKTypes1855() throws Exception
{
// apparently included by JDK?
_testIllegalType("com.sun.org.apache.bcel.internal.util.ClassLoader");
// also: we can try some form of testing, even if bit contrived...
_testIllegalType(BogusPointcutAdvisor.class);
_testIllegalType(BogusApplicationContext.class);
}
// 17-Aug-2017, tatu: Ideally would test handling of 3rd party types, too,
// but would require adding dependencies. This may be practical when
// checking done by separate module, but for now let's not do that for databind.
/*
public void testSpringTypes1737() throws Exception
{
_testIllegalType("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor");
_testIllegalType("org.springframework.beans.factory.config.PropertyPathFactoryBean");
}
*/
// // // Tests for [databind#1872]
public void testJDKTypes1872() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
String json = aposToQuotes(String.format("{'@class':'%s','authorities':['java.util.ArrayList',[]]}",
Authentication1872.class.getName()));
Authentication1872 result = mapper.readValue(json, Authentication1872.class);
assertNotNull(result);
}
// [databind#1931]
public void testC3P0Types() throws Exception
{
_testIllegalType(ComboPooledDataSource.class); // [databind#1931]
}
private void _testIllegalType(Class<?> nasty) throws Exception {
_testIllegalType(nasty.getName());
}
private void _testIllegalType(String clsName) throws Exception
{
// While usually exploited via default typing let's not require
// it here; mechanism still the same
String json = aposToQuotes(
"{'v':['"+clsName+"','/tmp/foobar.txt']}"
);
try {
MAPPER.readValue(json, PolyWrapper.class);
fail("Should not pass");
} catch (JsonMappingException e) {
_verifySecurityException(e, clsName);
}
}
protected void _verifySecurityException(Throwable t, String clsName) throws Exception
{
_verifyException(t, InvalidDefinitionException.class,
"Illegal type",
"to deserialize",
"prevented for security reasons");
verifyException(t, clsName);
}
protected void _verifyException(Throwable t, Class<?> expExcType,
String... patterns) throws Exception
{
Class<?> actExc = t.getClass();
if (!expExcType.isAssignableFrom(actExc)) {
fail("Expected Exception of type '"+expExcType.getName()+"', got '"
+actExc.getName()+"', message: "+t.getMessage());
}
for (String pattern : patterns) {
verifyException(t, pattern);
}
}
}