Replace whitelist with allowlist
This commit is contained in:
committed by
Gary Russell
parent
7ec1f5cc4b
commit
2419c03b25
@@ -11,7 +11,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id 'org.sonarqube' version '2.8'
|
||||
id 'io.spring.nohttp' version '0.0.4.RELEASE' apply false
|
||||
id 'io.spring.nohttp' version '0.0.5.RELEASE' apply false
|
||||
id 'org.ajoberstar.grgit' version '4.0.2'
|
||||
id "io.spring.dependency-management" version '1.0.9.RELEASE'
|
||||
id 'com.jfrog.artifactory' version '4.15.2' apply false
|
||||
@@ -25,7 +25,7 @@ if (System.getenv('TRAVIS') || System.getenv('bamboo_buildKey')) {
|
||||
apply plugin: 'io.spring.nohttp'
|
||||
|
||||
nohttp {
|
||||
whitelistFile = file('src/nohttp/whitelist.lines')
|
||||
allowlistFile = file('src/nohttp/allowlist.lines')
|
||||
source.include '**/src/**'
|
||||
source.exclude '**/*.gif', '**/*.jpg', '**/*.png', '**/*.svg', '**/*.ks'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.integration.transformer.PayloadDeserializingTransform
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class PayloadDeserializingTransformerParser extends AbstractTransformerParser {
|
||||
|
||||
@@ -38,7 +39,13 @@ public class PayloadDeserializingTransformerParser extends AbstractTransformerPa
|
||||
@Override
|
||||
protected void parseTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "deserializer");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "white-list", "whiteListPatterns");
|
||||
// TODO remove in 5.5
|
||||
if (element.hasAttribute("white-list")) {
|
||||
parserContext.getReaderContext().error(
|
||||
"the 'white-list' attribute is deprecated in favor of 'allow-list'", element);
|
||||
}
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "white-list", "allowedPatterns");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "allow-list", "allowedPatterns");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -215,14 +215,15 @@ public abstract class Transformers {
|
||||
return transformer;
|
||||
}
|
||||
|
||||
public static PayloadDeserializingTransformer deserializer(String... whiteListPatterns) {
|
||||
return deserializer(null, whiteListPatterns);
|
||||
public static PayloadDeserializingTransformer deserializer(String... allowedPatterns) {
|
||||
return deserializer(null, allowedPatterns);
|
||||
}
|
||||
|
||||
public static PayloadDeserializingTransformer deserializer(@Nullable Deserializer<Object> deserializer,
|
||||
String... whiteListPatterns) {
|
||||
String... allowedPatterns) {
|
||||
|
||||
PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer();
|
||||
transformer.setWhiteListPatterns(whiteListPatterns);
|
||||
transformer.setAllowedPatterns(allowedPatterns);
|
||||
if (deserializer != null) {
|
||||
transformer.setDeserializer(deserializer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.support.converter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.core.ConfigurableObjectInputStream;
|
||||
import org.springframework.core.NestedIOException;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.serializer.DefaultDeserializer;
|
||||
import org.springframework.core.serializer.Deserializer;
|
||||
import org.springframework.core.serializer.support.SerializationFailedException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
/**
|
||||
* A {@link Converter} that delegates to a
|
||||
* {@link Deserializer} to convert data in a byte
|
||||
* array to an object. By default, if using a {@link DefaultDeserializer} all
|
||||
* classes/packages are deserialized. If you receive data from untrusted sources, consider
|
||||
* adding trusted classes/packages using {@link #setAllowedPatterns(String...)} or
|
||||
* {@link #addAllowedPatterns(String...)}.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 5.4
|
||||
*/
|
||||
public class AllowListDeserializingConverter implements Converter<byte[], Object> {
|
||||
|
||||
private final Deserializer<Object> deserializer;
|
||||
|
||||
private final ClassLoader defaultDeserializerClassLoader;
|
||||
|
||||
private final boolean usingDefaultDeserializer;
|
||||
|
||||
private final Set<String> allowedPatterns = new LinkedHashSet<>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link AllowListDeserializingConverter} with default
|
||||
* {@link ObjectInputStream} configuration, using the "latest user-defined
|
||||
* ClassLoader".
|
||||
*/
|
||||
public AllowListDeserializingConverter() {
|
||||
this(new DefaultDeserializer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link AllowListDeserializingConverter} for using an
|
||||
* {@link ObjectInputStream} with the given {@code ClassLoader}.
|
||||
* @param classLoader the class loader to use for deserialization.
|
||||
*/
|
||||
public AllowListDeserializingConverter(ClassLoader classLoader) {
|
||||
this(new DefaultDeserializer(classLoader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link AllowListDeserializingConverter} that delegates to the provided
|
||||
* {@link Deserializer}.
|
||||
* @param deserializer the deserializer to use.
|
||||
*/
|
||||
public AllowListDeserializingConverter(Deserializer<Object> deserializer) {
|
||||
Assert.notNull(deserializer, "Deserializer must not be null");
|
||||
this.deserializer = deserializer;
|
||||
if (deserializer instanceof DefaultDeserializer) {
|
||||
ClassLoader classLoader = null;
|
||||
try {
|
||||
classLoader = (ClassLoader) new DirectFieldAccessor(deserializer).getPropertyValue("classLoader");
|
||||
}
|
||||
catch (Exception e) {
|
||||
// no-op
|
||||
}
|
||||
this.defaultDeserializerClassLoader = classLoader;
|
||||
this.usingDefaultDeserializer = true;
|
||||
}
|
||||
else {
|
||||
this.defaultDeserializerClassLoader = null;
|
||||
this.usingDefaultDeserializer = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set simple patterns for allowable packages/classes for deserialization.
|
||||
* The patterns will be applied in order until a match is found.
|
||||
* A class can be fully qualified or a wildcard '*' is allowed at the
|
||||
* beginning or end of the class name.
|
||||
* Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param allowedPatterns the patterns.
|
||||
*/
|
||||
public void setAllowedPatterns(String... allowedPatterns) {
|
||||
this.allowedPatterns.clear();
|
||||
Collections.addAll(this.allowedPatterns, allowedPatterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add package/class patterns to the allow list.
|
||||
* @param patterns the patterns to add.
|
||||
* @see #setAllowedPatterns(String...)
|
||||
*/
|
||||
public void addAllowedPatterns(String... patterns) {
|
||||
Collections.addAll(this.allowedPatterns, patterns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(byte[] source) {
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(source);
|
||||
try {
|
||||
if (this.usingDefaultDeserializer) {
|
||||
return deserialize(byteStream);
|
||||
}
|
||||
else {
|
||||
return this.deserializer.deserialize(byteStream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new SerializationFailedException("Failed to deserialize payload. " +
|
||||
"Is the byte array a result of corresponding serialization for " +
|
||||
this.deserializer.getClass().getSimpleName() + "?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object deserialize(ByteArrayInputStream inputStream) throws IOException {
|
||||
try {
|
||||
ObjectInputStream objectInputStream = new ConfigurableObjectInputStream(inputStream,
|
||||
this.defaultDeserializerClassLoader) {
|
||||
|
||||
@Override
|
||||
protected Class<?> resolveClass(ObjectStreamClass classDesc)
|
||||
throws IOException, ClassNotFoundException {
|
||||
Class<?> clazz = super.resolveClass(classDesc);
|
||||
checkAllowList(clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
};
|
||||
return objectInputStream.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new NestedIOException("Failed to deserialize object type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkAllowList(Class<?> clazz) {
|
||||
if (this.allowedPatterns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (clazz.isArray() || clazz.isPrimitive() || clazz.equals(String.class)
|
||||
|| Number.class.isAssignableFrom(clazz)) {
|
||||
return;
|
||||
}
|
||||
String className = clazz.getName();
|
||||
for (String pattern : this.allowedPatterns) {
|
||||
if (PatternMatchUtils.simpleMatch(pattern, className)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new SecurityException("Attempt to deserialize unauthorized " + clazz);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,23 +16,9 @@
|
||||
|
||||
package org.springframework.integration.support.converter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.core.ConfigurableObjectInputStream;
|
||||
import org.springframework.core.NestedIOException;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.serializer.DefaultDeserializer;
|
||||
import org.springframework.core.serializer.Deserializer;
|
||||
import org.springframework.core.serializer.support.SerializationFailedException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
/**
|
||||
* A {@link Converter} that delegates to a
|
||||
@@ -45,18 +31,13 @@ import org.springframework.util.PatternMatchUtils;
|
||||
* @author Gary Russell
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
*
|
||||
* @since 4.2.13
|
||||
*
|
||||
* @deprecated since 5.4 in favor of AllowListDeserializingConverter
|
||||
*/
|
||||
public class WhiteListDeserializingConverter implements Converter<byte[], Object> {
|
||||
|
||||
private final Deserializer<Object> deserializer;
|
||||
|
||||
private final ClassLoader defaultDeserializerClassLoader;
|
||||
|
||||
private final boolean usingDefaultDeserializer;
|
||||
|
||||
private final Set<String> whiteListPatterns = new LinkedHashSet<String>();
|
||||
|
||||
@Deprecated
|
||||
public class WhiteListDeserializingConverter extends AllowListDeserializingConverter {
|
||||
|
||||
/**
|
||||
* Create a {@code WhiteListDeserializingConverter} with default
|
||||
@@ -64,7 +45,7 @@ public class WhiteListDeserializingConverter implements Converter<byte[], Object
|
||||
* ClassLoader".
|
||||
*/
|
||||
public WhiteListDeserializingConverter() {
|
||||
this(new DefaultDeserializer());
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +54,7 @@ public class WhiteListDeserializingConverter implements Converter<byte[], Object
|
||||
* @param classLoader the class loader to use for deserialization.
|
||||
*/
|
||||
public WhiteListDeserializingConverter(ClassLoader classLoader) {
|
||||
this(new DefaultDeserializer(classLoader));
|
||||
super(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,23 +63,7 @@ public class WhiteListDeserializingConverter implements Converter<byte[], Object
|
||||
* @param deserializer the deserializer to use.
|
||||
*/
|
||||
public WhiteListDeserializingConverter(Deserializer<Object> deserializer) {
|
||||
Assert.notNull(deserializer, "Deserializer must not be null");
|
||||
this.deserializer = deserializer;
|
||||
if (deserializer instanceof DefaultDeserializer) {
|
||||
ClassLoader classLoader = null;
|
||||
try {
|
||||
classLoader = (ClassLoader) new DirectFieldAccessor(deserializer).getPropertyValue("classLoader");
|
||||
}
|
||||
catch (Exception e) {
|
||||
// no-op
|
||||
}
|
||||
this.defaultDeserializerClassLoader = classLoader;
|
||||
this.usingDefaultDeserializer = true;
|
||||
}
|
||||
else {
|
||||
this.defaultDeserializerClassLoader = null;
|
||||
this.usingDefaultDeserializer = false;
|
||||
}
|
||||
super(deserializer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,8 +75,7 @@ public class WhiteListDeserializingConverter implements Converter<byte[], Object
|
||||
* @param whiteListPatterns the patterns.
|
||||
*/
|
||||
public void setWhiteListPatterns(String... whiteListPatterns) {
|
||||
this.whiteListPatterns.clear();
|
||||
Collections.addAll(this.whiteListPatterns, whiteListPatterns);
|
||||
setAllowedPatterns(whiteListPatterns);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,63 +84,11 @@ public class WhiteListDeserializingConverter implements Converter<byte[], Object
|
||||
* @see #setWhiteListPatterns(String...)
|
||||
*/
|
||||
public void addWhiteListPatterns(String... patterns) {
|
||||
Collections.addAll(this.whiteListPatterns, patterns);
|
||||
addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(byte[] source) {
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(source);
|
||||
try {
|
||||
if (this.usingDefaultDeserializer) {
|
||||
return deserialize(byteStream);
|
||||
}
|
||||
else {
|
||||
return this.deserializer.deserialize(byteStream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new SerializationFailedException("Failed to deserialize payload. " +
|
||||
"Is the byte array a result of corresponding serialization for " +
|
||||
this.deserializer.getClass().getSimpleName() + "?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object deserialize(ByteArrayInputStream inputStream) throws IOException {
|
||||
try {
|
||||
ObjectInputStream objectInputStream = new ConfigurableObjectInputStream(inputStream,
|
||||
this.defaultDeserializerClassLoader) {
|
||||
|
||||
@Override
|
||||
protected Class<?> resolveClass(ObjectStreamClass classDesc)
|
||||
throws IOException, ClassNotFoundException {
|
||||
Class<?> clazz = super.resolveClass(classDesc);
|
||||
checkWhiteList(clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
};
|
||||
return objectInputStream.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new NestedIOException("Failed to deserialize object type", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkWhiteList(Class<?> clazz) throws IOException {
|
||||
if (this.whiteListPatterns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (clazz.isArray() || clazz.isPrimitive() || clazz.equals(String.class)
|
||||
|| Number.class.isAssignableFrom(clazz)) {
|
||||
return;
|
||||
}
|
||||
String className = clazz.getName();
|
||||
for (String pattern : this.whiteListPatterns) {
|
||||
if (PatternMatchUtils.simpleMatch(pattern, className)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new SecurityException("Attempt to deserialize unauthorized " + clazz);
|
||||
protected void checkWhiteList(Class<?> clazz) {
|
||||
checkAllowList(clazz);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public final class JacksonJsonUtils {
|
||||
if (JacksonPresent.isJackson2Present()) {
|
||||
ObjectMapper mapper = new Jackson2JsonObjectMapper().getObjectMapper();
|
||||
|
||||
mapper.setDefaultTyping(new WhitelistTypeResolverBuilder(trustedPackages));
|
||||
mapper.setDefaultTyping(new AllowlistTypeResolverBuilder(trustedPackages));
|
||||
|
||||
GenericMessageJacksonDeserializer genericMessageDeserializer = new GenericMessageJacksonDeserializer();
|
||||
genericMessageDeserializer.setMapper(mapper);
|
||||
@@ -98,7 +98,7 @@ public final class JacksonJsonUtils {
|
||||
|
||||
/**
|
||||
* An implementation of {@link ObjectMapper.DefaultTypeResolverBuilder}
|
||||
* that wraps a default {@link TypeIdResolver} to the {@link WhitelistTypeIdResolver}.
|
||||
* that wraps a default {@link TypeIdResolver} to the {@link AllowlistTypeIdResolver}.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Artem Bilan
|
||||
@@ -107,13 +107,13 @@ public final class JacksonJsonUtils {
|
||||
*
|
||||
* @since 4.3.11
|
||||
*/
|
||||
private static final class WhitelistTypeResolverBuilder extends ObjectMapper.DefaultTypeResolverBuilder {
|
||||
private static final class AllowlistTypeResolverBuilder extends ObjectMapper.DefaultTypeResolverBuilder {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String[] trustedPackages;
|
||||
|
||||
WhitelistTypeResolverBuilder(String... trustedPackages) {
|
||||
AllowlistTypeResolverBuilder(String... trustedPackages) {
|
||||
super(ObjectMapper.DefaultTyping.NON_FINAL,
|
||||
//we do explicit validation in the TypeIdResolver
|
||||
BasicPolymorphicTypeValidator.builder()
|
||||
@@ -133,7 +133,7 @@ public final class JacksonJsonUtils {
|
||||
PolymorphicTypeValidator subtypeValidator,
|
||||
Collection<NamedType> subtypes, boolean forSer, boolean forDeser) {
|
||||
TypeIdResolver result = super.idResolver(config, baseType, subtypeValidator, subtypes, forSer, forDeser);
|
||||
return new WhitelistTypeIdResolver(result, this.trustedPackages);
|
||||
return new AllowlistTypeIdResolver(result, this.trustedPackages);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public final class JacksonJsonUtils {
|
||||
*
|
||||
* @since 4.3.11
|
||||
*/
|
||||
private static final class WhitelistTypeIdResolver implements TypeIdResolver {
|
||||
private static final class AllowlistTypeIdResolver implements TypeIdResolver {
|
||||
|
||||
private static final List<String> TRUSTED_PACKAGES =
|
||||
Arrays.asList(
|
||||
@@ -164,7 +164,7 @@ public final class JacksonJsonUtils {
|
||||
|
||||
private final Set<String> trustedPackages = new LinkedHashSet<>(TRUSTED_PACKAGES);
|
||||
|
||||
WhitelistTypeIdResolver(TypeIdResolver delegate, String... trustedPackages) {
|
||||
AllowlistTypeIdResolver(TypeIdResolver delegate, String... trustedPackages) {
|
||||
this.delegate = delegate;
|
||||
if (trustedPackages != null) {
|
||||
for (String whiteListPackage : trustedPackages) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,13 +17,14 @@
|
||||
package org.springframework.integration.transformer;
|
||||
|
||||
import org.springframework.core.serializer.Deserializer;
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Transformer that deserializes the inbound byte array payload to an object by delegating
|
||||
* to a Converter<byte[], Object>. Default delegate is a
|
||||
* {@link WhiteListDeserializingConverter} using Java serialization.
|
||||
* {@link AllowListDeserializingConverter} using Java serialization.
|
||||
*
|
||||
* <p>
|
||||
* The byte array payload must be a result of equivalent serialization.
|
||||
@@ -37,30 +38,45 @@ import org.springframework.util.Assert;
|
||||
public class PayloadDeserializingTransformer extends PayloadTypeConvertingTransformer<byte[], Object> {
|
||||
|
||||
/**
|
||||
* Instantiate based on the {@link WhiteListDeserializingConverter} with the
|
||||
* Instantiate based on the {@link AllowListDeserializingConverter} with the
|
||||
* {@link org.springframework.core.serializer.DefaultDeserializer}.
|
||||
*/
|
||||
public PayloadDeserializingTransformer() {
|
||||
doSetConverter(new WhiteListDeserializingConverter());
|
||||
doSetConverter(new AllowListDeserializingConverter());
|
||||
}
|
||||
|
||||
public void setDeserializer(Deserializer<Object> deserializer) {
|
||||
setConverter(new WhiteListDeserializingConverter(deserializer));
|
||||
setConverter(new AllowListDeserializingConverter(deserializer));
|
||||
}
|
||||
|
||||
/**
|
||||
* When using a {@link WhiteListDeserializingConverter} (the default) add patterns
|
||||
* When using a {@link AllowListDeserializingConverter} (the default) add patterns
|
||||
* for packages/classes that are allowed to be deserialized.
|
||||
* A class can be fully qualified or a wildcard '*' is allowed at the
|
||||
* beginning or end of the class name.
|
||||
* Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 4.2.13
|
||||
* @deprecated since 5.4 in favor of {@link #setAllowedPatterns(String...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setWhiteListPatterns(String... patterns) {
|
||||
Assert.isTrue(getConverter() instanceof WhiteListDeserializingConverter,
|
||||
"Patterns can only be provided when using a 'WhiteListDeserializingConverter'");
|
||||
((WhiteListDeserializingConverter) getConverter()).setWhiteListPatterns(patterns);
|
||||
setAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* When using a {@link AllowListDeserializingConverter} (the default) add patterns
|
||||
* for packages/classes that are allowed to be deserialized.
|
||||
* A class can be fully qualified or a wildcard '*' is allowed at the
|
||||
* beginning or end of the class name.
|
||||
* Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void setAllowedPatterns(String... patterns) {
|
||||
Assert.isTrue(getConverter() instanceof AllowListDeserializingConverter,
|
||||
"Patterns can only be provided when using a 'AllowListDeserializingConverter'");
|
||||
((AllowListDeserializingConverter) getConverter()).setAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2788,6 +2788,16 @@
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="white-list">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
[DEPRECATED]
|
||||
When using the default Deserializer, a list of package/class patterns indicating
|
||||
classes that are allowed to be deserialized. Consider providing this if you receive
|
||||
data from untrusted sources. Example: "com.mycom.*, com.yourcom.*".
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="allow-list">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
When using the default Deserializer, a list of package/class patterns indicating
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</channel>
|
||||
|
||||
<payload-deserializing-transformer id="direct" input-channel="directInput" output-channel="output"
|
||||
white-list="*" />
|
||||
allow-list="*" />
|
||||
|
||||
<payload-deserializing-transformer input-channel="queueInput" output-channel="output">
|
||||
<poller fixed-delay="10000"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -24,10 +25,10 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -39,15 +40,14 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringJUnitConfig
|
||||
public class PayloadDeserializingTransformerParserTests {
|
||||
|
||||
@Autowired
|
||||
@@ -75,8 +75,8 @@ public class PayloadDeserializingTransformerParserTests {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload() instanceof String).isTrue();
|
||||
assertThat(result.getPayload()).isEqualTo("foo");
|
||||
Set<?> patterns = TestUtils.getPropertyValue(this.handler, "transformer.converter.whiteListPatterns",
|
||||
Set.class);
|
||||
Set<?> patterns =
|
||||
TestUtils.getPropertyValue(this.handler, "transformer.converter.allowedPatterns", Set.class);
|
||||
assertThat(patterns.size()).isEqualTo(1);
|
||||
assertThat(patterns.iterator().next()).isEqualTo("*");
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class PayloadDeserializingTransformerParserTests {
|
||||
@Test
|
||||
public void queueChannelWithSerializedStringMessage() throws Exception {
|
||||
byte[] bytes = serialize("foo");
|
||||
queueInput.send(new GenericMessage<byte[]>(bytes));
|
||||
queueInput.send(new GenericMessage<>(bytes));
|
||||
Message<?> result = output.receive(10000);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload() instanceof String).isTrue();
|
||||
@@ -94,7 +94,7 @@ public class PayloadDeserializingTransformerParserTests {
|
||||
@Test
|
||||
public void directChannelWithSerializedObjectMessage() throws Exception {
|
||||
byte[] bytes = serialize(new TestBean());
|
||||
directInput.send(new GenericMessage<byte[]>(bytes));
|
||||
directInput.send(new GenericMessage<>(bytes));
|
||||
Message<?> result = output.receive(10000);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload().getClass()).isEqualTo(TestBean.class);
|
||||
@@ -104,22 +104,23 @@ public class PayloadDeserializingTransformerParserTests {
|
||||
@Test
|
||||
public void queueChannelWithSerializedObjectMessage() throws Exception {
|
||||
byte[] bytes = serialize(new TestBean());
|
||||
queueInput.send(new GenericMessage<byte[]>(bytes));
|
||||
queueInput.send(new GenericMessage<>(bytes));
|
||||
Message<?> result = output.receive(10000);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload().getClass()).isEqualTo(TestBean.class);
|
||||
assertThat(((TestBean) result.getPayload()).name).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test(expected = MessageTransformationException.class)
|
||||
@Test
|
||||
public void invalidPayload() {
|
||||
byte[] bytes = new byte[] { 1, 2, 3 };
|
||||
directInput.send(new GenericMessage<byte[]>(bytes));
|
||||
byte[] bytes = {1, 2, 3};
|
||||
assertThatExceptionOfType(MessageTransformationException.class)
|
||||
.isThrownBy(() -> directInput.send(new GenericMessage<>(bytes)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customDeserializer() throws Exception {
|
||||
customDeserializerInput.send(new GenericMessage<byte[]>("test".getBytes("UTF-8")));
|
||||
public void customDeserializer() {
|
||||
customDeserializerInput.send(new GenericMessage<>("test".getBytes(StandardCharsets.UTF_8)));
|
||||
Message<?> result = output.receive(10000);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload().getClass()).isEqualTo(String.class);
|
||||
@@ -151,7 +152,7 @@ public class PayloadDeserializingTransformerParserTests {
|
||||
|
||||
@Override
|
||||
public Object deserialize(InputStream source) throws IOException {
|
||||
return FileCopyUtils.copyToString(new InputStreamReader(source, "UTF-8")).toUpperCase();
|
||||
return FileCopyUtils.copyToString(new InputStreamReader(source, StandardCharsets.UTF_8)).toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,13 +17,14 @@
|
||||
package org.springframework.integration.transformer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class PayloadDeserializingTransformerTests {
|
||||
|
||||
@@ -41,7 +43,7 @@ public class PayloadDeserializingTransformerTests {
|
||||
objectStream.writeObject("foo");
|
||||
byte[] serialized = byteStream.toByteArray();
|
||||
PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer();
|
||||
Message<?> result = transformer.transform(new GenericMessage<byte[]>(serialized));
|
||||
Message<?> result = transformer.transform(new GenericMessage<>(serialized));
|
||||
Object payload = result.getPayload();
|
||||
assertThat(payload).isNotNull();
|
||||
assertThat(payload.getClass()).isEqualTo(String.class);
|
||||
@@ -56,7 +58,7 @@ public class PayloadDeserializingTransformerTests {
|
||||
objectStream.writeObject(testBean);
|
||||
byte[] serialized = byteStream.toByteArray();
|
||||
PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer();
|
||||
Message<?> result = transformer.transform(new GenericMessage<byte[]>(serialized));
|
||||
Message<?> result = transformer.transform(new GenericMessage<>(serialized));
|
||||
Object payload = result.getPayload();
|
||||
assertThat(payload).isNotNull();
|
||||
assertThat(payload.getClass()).isEqualTo(TestBean.class);
|
||||
@@ -64,35 +66,36 @@ public class PayloadDeserializingTransformerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeObjectWhiteList() throws Exception {
|
||||
public void deserializeObjectAllowList() throws Exception {
|
||||
TestBean testBean = new TestBean("test");
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
|
||||
objectStream.writeObject(testBean);
|
||||
byte[] serialized = byteStream.toByteArray();
|
||||
PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer();
|
||||
transformer.setWhiteListPatterns("com.*");
|
||||
transformer.setAllowedPatterns("com.*");
|
||||
try {
|
||||
transformer.transform(new GenericMessage<byte[]>(serialized));
|
||||
transformer.transform(new GenericMessage<>(serialized));
|
||||
fail("expected security exception");
|
||||
}
|
||||
catch (MessageTransformationException e) {
|
||||
assertThat(e.getCause().getCause()).isInstanceOf(SecurityException.class);
|
||||
assertThat(e.getCause().getCause().getMessage()).startsWith("Attempt to deserialize unauthorized");
|
||||
}
|
||||
transformer.setWhiteListPatterns("org.*");
|
||||
Message<?> result = transformer.transform(new GenericMessage<byte[]>(serialized));
|
||||
transformer.setAllowedPatterns("org.*");
|
||||
Message<?> result = transformer.transform(new GenericMessage<>(serialized));
|
||||
Object payload = result.getPayload();
|
||||
assertThat(payload).isNotNull();
|
||||
assertThat(payload.getClass()).isEqualTo(TestBean.class);
|
||||
assertThat(((TestBean) payload).name).isEqualTo(testBean.name);
|
||||
}
|
||||
|
||||
@Test(expected = MessageTransformationException.class)
|
||||
@Test
|
||||
public void invalidPayload() {
|
||||
byte[] bytes = new byte[] { 1, 2, 3 };
|
||||
byte[] bytes = {1, 2, 3};
|
||||
PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer();
|
||||
transformer.transform(new GenericMessage<byte[]>(bytes));
|
||||
assertThatExceptionOfType(MessageTransformationException.class)
|
||||
.isThrownBy(() -> transformer.transform(new GenericMessage<>(bytes)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,6 +114,7 @@ public class PayloadDeserializingTransformerTests {
|
||||
TestBean(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupFactory;
|
||||
import org.springframework.integration.store.PriorityCapableChannelMessageStore;
|
||||
import org.springframework.integration.store.SimpleMessageGroupFactory;
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.integration.util.UUIDConverter;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
@@ -130,7 +130,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private WhiteListDeserializingConverter deserializer;
|
||||
private AllowListDeserializingConverter deserializer;
|
||||
|
||||
private SerializingConverter serializer;
|
||||
|
||||
@@ -152,7 +152,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* Convenient constructor for configuration use.
|
||||
*/
|
||||
public JdbcChannelMessageStore() {
|
||||
this.deserializer = new WhiteListDeserializingConverter();
|
||||
this.deserializer = new AllowListDeserializingConverter();
|
||||
this.serializer = new SerializingConverter();
|
||||
}
|
||||
|
||||
@@ -188,9 +188,9 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* A converter for deserializing byte arrays to messages.
|
||||
* @param deserializer the deserializer to set
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void setDeserializer(Deserializer<? extends Message<?>> deserializer) {
|
||||
this.deserializer = new WhiteListDeserializingConverter((Deserializer) deserializer);
|
||||
this.deserializer = new AllowListDeserializingConverter((Deserializer) deserializer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,9 +199,22 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 4.2.13
|
||||
* @deprecated since 5.4 in favor of {@link #addAllowedPatterns(String...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void addWhiteListPatterns(String... patterns) {
|
||||
this.deserializer.addWhiteListPatterns(patterns);
|
||||
addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add patterns for packages/classes that are allowed to be deserialized. A class can
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void addAllowedPatterns(String... patterns) {
|
||||
this.deserializer.addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,7 +421,7 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
public MessageGroup addMessageToGroup(Object groupId, final Message<?> message) {
|
||||
try {
|
||||
this.jdbcTemplate.update(getQuery(Query.CREATE_MESSAGE,
|
||||
() -> this.channelMessageStoreQueryProvider.getCreateMessageQuery()),
|
||||
() -> this.channelMessageStoreQueryProvider.getCreateMessageQuery()),
|
||||
ps -> this.preparedStatementSetter.setValues(ps, message, groupId, this.region,
|
||||
this.priorityEnabled));
|
||||
}
|
||||
@@ -588,8 +601,8 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
|
||||
|
||||
int updated = this.jdbcTemplate.update(
|
||||
getQuery(Query.DELETE_MESSAGE, () -> this.channelMessageStoreQueryProvider.getDeleteMessageQuery()),
|
||||
new Object[] { getKey(id), getKey(groupId), this.region },
|
||||
new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR });
|
||||
new Object[]{getKey(id), getKey(groupId), this.region},
|
||||
new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR});
|
||||
|
||||
boolean result = updated != 0;
|
||||
if (result) {
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageMetadata;
|
||||
import org.springframework.integration.store.MessageStore;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.integration.util.UUIDConverter;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -173,7 +173,7 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
|
||||
|
||||
private String tablePrefix = DEFAULT_TABLE_PREFIX;
|
||||
|
||||
private WhiteListDeserializingConverter deserializer;
|
||||
private AllowListDeserializingConverter deserializer;
|
||||
|
||||
private SerializingConverter serializer;
|
||||
|
||||
@@ -195,7 +195,7 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
|
||||
public JdbcMessageStore(JdbcOperations jdbcOperations) {
|
||||
Assert.notNull(jdbcOperations, "'dataSource' must not be null");
|
||||
this.jdbcTemplate = jdbcOperations;
|
||||
this.deserializer = new WhiteListDeserializingConverter();
|
||||
this.deserializer = new AllowListDeserializingConverter();
|
||||
this.serializer = new SerializingConverter();
|
||||
}
|
||||
|
||||
@@ -245,9 +245,9 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
|
||||
*
|
||||
* @param deserializer the deserializer to set
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void setDeserializer(Deserializer<? extends Message<?>> deserializer) {
|
||||
this.deserializer = new WhiteListDeserializingConverter((Deserializer) deserializer);
|
||||
this.deserializer = new AllowListDeserializingConverter((Deserializer) deserializer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,9 +256,22 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 4.2.13
|
||||
* @deprecated since 5.4 in favor of {@link #addAllowedPatterns(String...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void addWhiteListPatterns(String... patterns) {
|
||||
this.deserializer.addWhiteListPatterns(patterns);
|
||||
addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add patterns for packages/classes that are allowed to be deserialized. A class can
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void addAllowedPatterns(String... patterns) {
|
||||
this.deserializer.addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,7 @@ package org.springframework.integration.jdbc.store.channel;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.support.lob.LobHandler;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -31,16 +31,17 @@ import org.springframework.messaging.Message;
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
public class MessageRowMapper implements RowMapper<Message<?>> {
|
||||
|
||||
private final WhiteListDeserializingConverter deserializer;
|
||||
private final AllowListDeserializingConverter deserializer;
|
||||
|
||||
private final LobHandler lobHandler;
|
||||
|
||||
public MessageRowMapper(WhiteListDeserializingConverter deserializer, LobHandler lobHandler) {
|
||||
public MessageRowMapper(AllowListDeserializingConverter deserializer, LobHandler lobHandler) {
|
||||
this.deserializer = deserializer;
|
||||
this.lobHandler = lobHandler;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ import org.springframework.integration.store.MessageStore;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
import org.springframework.integration.support.MutableMessage;
|
||||
import org.springframework.integration.support.MutableMessageBuilder;
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -138,7 +138,7 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private String[] whiteListPatterns;
|
||||
private String[] allowedPatterns;
|
||||
|
||||
/**
|
||||
* Create a MongoDbMessageStore using the provided {@link MongoDatabaseFactory}.and the default collection name.
|
||||
@@ -177,9 +177,22 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @deprecated since 5.4 in favor of {@link #addAllowedPatterns(String...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void addWhiteListPatterns(String... patterns) {
|
||||
this.whiteListPatterns = patterns != null ? Arrays.copyOf(patterns, patterns.length) : null;
|
||||
addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add patterns for packages/classes that are allowed to be deserialized. A class can
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void addAllowedPatterns(String... patterns) {
|
||||
this.allowedPatterns = patterns != null ? Arrays.copyOf(patterns, patterns.length) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -540,9 +553,9 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
converters.add(new DocumentToGenericMessageConverter());
|
||||
converters.add(new DocumentToMutableMessageConverter());
|
||||
DocumentToErrorMessageConverter docToErrorMessageConverter = new DocumentToErrorMessageConverter();
|
||||
if (MongoDbMessageStore.this.whiteListPatterns != null) {
|
||||
if (MongoDbMessageStore.this.allowedPatterns != null) {
|
||||
docToErrorMessageConverter.deserializingConverter
|
||||
.addWhiteListPatterns(MongoDbMessageStore.this.whiteListPatterns);
|
||||
.addAllowedPatterns(MongoDbMessageStore.this.allowedPatterns);
|
||||
}
|
||||
converters.add(docToErrorMessageConverter);
|
||||
converters.add(new DocumentToAdviceMessageConverter());
|
||||
@@ -772,7 +785,7 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore
|
||||
@ReadingConverter
|
||||
private class DocumentToErrorMessageConverter implements Converter<Document, ErrorMessage> {
|
||||
|
||||
private final WhiteListDeserializingConverter deserializingConverter = new WhiteListDeserializingConverter();
|
||||
private final AllowListDeserializingConverter deserializingConverter = new AllowListDeserializingConverter();
|
||||
|
||||
DocumentToErrorMessageConverter() {
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2019 the original author or authors.
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@ import org.bson.types.Binary;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.integration.support.converter.WhiteListDeserializingConverter;
|
||||
import org.springframework.integration.support.converter.AllowListDeserializingConverter;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,7 @@ import org.springframework.messaging.Message;
|
||||
@ReadingConverter
|
||||
public class BinaryToMessageConverter implements Converter<Binary, Message<?>> {
|
||||
|
||||
private final WhiteListDeserializingConverter deserializingConverter = new WhiteListDeserializingConverter();
|
||||
private final AllowListDeserializingConverter deserializingConverter = new AllowListDeserializingConverter();
|
||||
|
||||
@Override
|
||||
public Message<?> convert(Binary source) {
|
||||
@@ -43,9 +43,22 @@ public class BinaryToMessageConverter implements Converter<Binary, Message<?>> {
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @deprecated since 5.4 in favor of {@link #addAllowedPatterns(String...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void addWhiteListPatterns(String... patterns) {
|
||||
this.deserializingConverter.addWhiteListPatterns(patterns);
|
||||
this.deserializingConverter.addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add patterns for packages/classes that are allowed to be deserialized. A class can
|
||||
* be fully qualified or a wildcard '*' is allowed at the beginning or end of the
|
||||
* class name. Examples: {@code com.foo.*}, {@code *.MyClass}.
|
||||
* @param patterns the patterns.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void addAllowedPatterns(String... patterns) {
|
||||
this.deserializingConverter.addAllowedPatterns(patterns);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -131,11 +131,11 @@ The following example shows to use Spring's serializer and deserializer:
|
||||
<int:payload-serializing-transformer input-channel="objectsIn" output-channel="bytesOut"/>
|
||||
|
||||
<int:payload-deserializing-transformer input-channel="bytesIn" output-channel="objectsOut"
|
||||
white-list="com.mycom.*,com.yourcom.*"/>
|
||||
allow-list="com.mycom.*,com.yourcom.*"/>
|
||||
----
|
||||
====
|
||||
|
||||
IMPORTANT: When deserializing data from untrusted sources, you should consider adding a `white-list` of package and class patterns.
|
||||
IMPORTANT: When deserializing data from untrusted sources, you should consider adding a `allow-list` of package and class patterns.
|
||||
By default, all classes are deserialized.
|
||||
|
||||
===== `Object`-to-`Map` and `Map`-to-`Object` Transformers
|
||||
|
||||
Reference in New Issue
Block a user