From 2419c03b254cf404260236f3b7fb5bb0987a4346 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 11 Jun 2020 18:04:28 -0400 Subject: [PATCH] Replace `whitelist` with `allowlist` --- build.gradle | 4 +- ...PayloadDeserializingTransformerParser.java | 11 +- .../integration/dsl/Transformers.java | 11 +- .../AllowListDeserializingConverter.java | 184 ++++++++++++++++++ .../WhiteListDeserializingConverter.java | 114 ++--------- .../support/json/JacksonJsonUtils.java | 14 +- .../PayloadDeserializingTransformer.java | 36 +++- .../integration/config/spring-integration.xsd | 10 + ...ializingTransformerParserTests-context.xml | 2 +- ...adDeserializingTransformerParserTests.java | 37 ++-- .../PayloadDeserializingTransformerTests.java | 28 +-- .../jdbc/store/JdbcChannelMessageStore.java | 31 ++- .../jdbc/store/JdbcMessageStore.java | 25 ++- .../jdbc/store/channel/MessageRowMapper.java | 9 +- .../mongodb/store/MongoDbMessageStore.java | 25 ++- .../support/BinaryToMessageConverter.java | 21 +- .../{whitelist.lines => allowlist.lines} | 0 src/reference/asciidoc/transformer.adoc | 4 +- 18 files changed, 377 insertions(+), 189 deletions(-) create mode 100644 spring-integration-core/src/main/java/org/springframework/integration/support/converter/AllowListDeserializingConverter.java rename src/nohttp/{whitelist.lines => allowlist.lines} (100%) diff --git a/build.gradle b/build.gradle index af3bc987c72..58af78f2dd5 100644 --- a/build.gradle +++ b/build.gradle @@ -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' } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParser.java index 36a6e7711e8..ba4a110074a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParser.java @@ -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 @@ * * @author Mark Fisher * @author Gary Russell + * @author Artem Bilan */ public class PayloadDeserializingTransformerParser extends AbstractTransformerParser { @@ -38,7 +39,13 @@ protected String getTransformerClassName() { @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"); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/Transformers.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/Transformers.java index 2d70112b054..cad6d15d332 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/Transformers.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/Transformers.java @@ -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 static PayloadSerializingTransformer serializer(@Nullable Serializer deserializer, - String... whiteListPatterns) { + String... allowedPatterns) { + PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer(); - transformer.setWhiteListPatterns(whiteListPatterns); + transformer.setAllowedPatterns(allowedPatterns); if (deserializer != null) { transformer.setDeserializer(deserializer); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/converter/AllowListDeserializingConverter.java b/spring-integration-core/src/main/java/org/springframework/integration/support/converter/AllowListDeserializingConverter.java new file mode 100644 index 00000000000..891b79d4272 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/converter/AllowListDeserializingConverter.java @@ -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 { + + private final Deserializer deserializer; + + private final ClassLoader defaultDeserializerClassLoader; + + private final boolean usingDefaultDeserializer; + + private final Set 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 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); + } + +} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/converter/WhiteListDeserializingConverter.java b/spring-integration-core/src/main/java/org/springframework/integration/support/converter/WhiteListDeserializingConverter.java index e0e8ac85005..874049d2468 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/converter/WhiteListDeserializingConverter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/converter/WhiteListDeserializingConverter.java @@ -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 @@ * @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 { - - private final Deserializer deserializer; - - private final ClassLoader defaultDeserializerClassLoader; - - private final boolean usingDefaultDeserializer; - - private final Set whiteListPatterns = new LinkedHashSet(); - +@Deprecated +public class WhiteListDeserializingConverter extends AllowListDeserializingConverter { /** * Create a {@code WhiteListDeserializingConverter} with default @@ -64,7 +45,7 @@ public class WhiteListDeserializingConverter implements Converter 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 WhiteListDeserializingConverter(Deserializer deserializer) { * @param whiteListPatterns the patterns. */ public void setWhiteListPatterns(String... whiteListPatterns) { - this.whiteListPatterns.clear(); - Collections.addAll(this.whiteListPatterns, whiteListPatterns); + setAllowedPatterns(whiteListPatterns); } /** @@ -120,63 +84,11 @@ public void setWhiteListPatterns(String... whiteListPatterns) { * @see #setWhiteListPatterns(String...) */ public void addWhiteListPatterns(String... patterns) { - Collections.addAll(this.whiteListPatterns, 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); - } + addAllowedPatterns(patterns); } - 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); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/json/JacksonJsonUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/support/json/JacksonJsonUtils.java index abec1de7591..9b17ed4c1a6 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/json/JacksonJsonUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/json/JacksonJsonUtils.java @@ -67,7 +67,7 @@ public static ObjectMapper messagingAwareMapper(String... trustedPackages) { 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 static ObjectMapper messagingAwareMapper(String... trustedPackages) { /** * 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 static ObjectMapper messagingAwareMapper(String... trustedPackages) { * * @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 @@ protected TypeIdResolver idResolver(MapperConfig config, PolymorphicTypeValidator subtypeValidator, Collection 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 @@ protected TypeIdResolver idResolver(MapperConfig config, * * @since 4.3.11 */ - private static final class WhitelistTypeIdResolver implements TypeIdResolver { + private static final class AllowlistTypeIdResolver implements TypeIdResolver { private static final List TRUSTED_PACKAGES = Arrays.asList( @@ -164,7 +164,7 @@ private static final class WhitelistTypeIdResolver implements TypeIdResolver { private final Set 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) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/PayloadDeserializingTransformer.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/PayloadDeserializingTransformer.java index 1119ec281c2..e4d1f984fee 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/PayloadDeserializingTransformer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/PayloadDeserializingTransformer.java @@ -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. * *

* The byte array payload must be a result of equivalent serialization. @@ -37,30 +38,45 @@ public class PayloadDeserializingTransformer extends PayloadTypeConvertingTransformer { /** - * 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 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); } } diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration.xsd index 807bf72e22e..3fe02152162 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/spring-integration.xsd @@ -2788,6 +2788,16 @@ + + + [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.*". + + + + When using the default Deserializer, a list of package/class patterns indicating diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml index d2b1f532de6..265297de29b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml @@ -20,7 +20,7 @@ + allow-list="*" /> diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests.java index ac05ee4c2f3..ad059477b03 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests.java @@ -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.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.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 void directChannelWithSerializedStringMessage() throws Exception { 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 void directChannelWithSerializedStringMessage() throws Exception { @Test public void queueChannelWithSerializedStringMessage() throws Exception { byte[] bytes = serialize("foo"); - queueInput.send(new GenericMessage(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 void queueChannelWithSerializedStringMessage() throws Exception { @Test public void directChannelWithSerializedObjectMessage() throws Exception { byte[] bytes = serialize(new TestBean()); - directInput.send(new GenericMessage(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 void directChannelWithSerializedObjectMessage() throws Exception { @Test public void queueChannelWithSerializedObjectMessage() throws Exception { byte[] bytes = serialize(new TestBean()); - queueInput.send(new GenericMessage(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(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("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 static class TestDeserializer implements Deserializer { @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(); } } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/PayloadDeserializingTransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/PayloadDeserializingTransformerTests.java index 2797a0e4a8c..1292dacfec7 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/PayloadDeserializingTransformerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/PayloadDeserializingTransformerTests.java @@ -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 @@ /** * @author Mark Fisher + * @author Artem Bilan */ public class PayloadDeserializingTransformerTests { @@ -41,7 +43,7 @@ public void deserializeString() throws Exception { objectStream.writeObject("foo"); byte[] serialized = byteStream.toByteArray(); PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer(); - Message result = transformer.transform(new GenericMessage(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 void deserializeObject() throws Exception { objectStream.writeObject(testBean); byte[] serialized = byteStream.toByteArray(); PayloadDeserializingTransformer transformer = new PayloadDeserializingTransformer(); - Message result = transformer.transform(new GenericMessage(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 void deserializeObject() throws Exception { } @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(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(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(bytes)); + assertThatExceptionOfType(MessageTransformationException.class) + .isThrownBy(() -> transformer.transform(new GenericMessage<>(bytes))); } @Test @@ -111,6 +114,7 @@ private static class TestBean implements Serializable { TestBean(String name) { this.name = name; } + } } diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java index 31cd0f8e8fb..184019f7d44 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java @@ -45,7 +45,7 @@ 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 @@ private enum Query { private JdbcTemplate jdbcTemplate; - private WhiteListDeserializingConverter deserializer; + private AllowListDeserializingConverter deserializer; private SerializingConverter serializer; @@ -152,7 +152,7 @@ private enum Query { * Convenient constructor for configuration use. */ public JdbcChannelMessageStore() { - this.deserializer = new WhiteListDeserializingConverter(); + this.deserializer = new AllowListDeserializingConverter(); this.serializer = new SerializingConverter(); } @@ -188,9 +188,9 @@ public void setDataSource(DataSource dataSource) { * A converter for deserializing byte arrays to messages. * @param deserializer the deserializer to set */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) public void setDeserializer(Deserializer> deserializer) { - this.deserializer = new WhiteListDeserializingConverter((Deserializer) deserializer); + this.deserializer = new AllowListDeserializingConverter((Deserializer) deserializer); } /** @@ -199,9 +199,22 @@ public void setDeserializer(Deserializer> deserializer) { * 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 void afterPropertiesSet() { 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 @@ private boolean doRemoveMessageFromGroup(Object groupId, Message messageToRem 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) { diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java index b8287a2aeb0..e77390764e2 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java @@ -40,7 +40,7 @@ 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 String getSql() { private String tablePrefix = DEFAULT_TABLE_PREFIX; - private WhiteListDeserializingConverter deserializer; + private AllowListDeserializingConverter deserializer; private SerializingConverter serializer; @@ -195,7 +195,7 @@ public JdbcMessageStore(DataSource dataSource) { 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 void setSerializer(Serializer> serializer) { * * @param deserializer the deserializer to set */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) public void setDeserializer(Deserializer> deserializer) { - this.deserializer = new WhiteListDeserializingConverter((Deserializer) deserializer); + this.deserializer = new AllowListDeserializingConverter((Deserializer) deserializer); } /** @@ -256,9 +256,22 @@ public void setDeserializer(Deserializer> deserializer) { * 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 diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/channel/MessageRowMapper.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/channel/MessageRowMapper.java index fd6348c2a3b..852f83fcec9 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/channel/MessageRowMapper.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/channel/MessageRowMapper.java @@ -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 @@ 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 @@ * * @author Gunnar Hillert * @author Gary Russell + * * @since 2.2 * */ public class MessageRowMapper implements RowMapper> { - 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; } diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java index 784fb25dbb5..9fc2b751b81 100644 --- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java @@ -71,7 +71,7 @@ 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 void setApplicationContext(ApplicationContext applicationContext) throws * 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 void afterPropertiesSet() { 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 AdviceMessage convert(Document source) { @ReadingConverter private class DocumentToErrorMessageConverter implements Converter { - private final WhiteListDeserializingConverter deserializingConverter = new WhiteListDeserializingConverter(); + private final AllowListDeserializingConverter deserializingConverter = new AllowListDeserializingConverter(); DocumentToErrorMessageConverter() { } diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/BinaryToMessageConverter.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/BinaryToMessageConverter.java index d65ff120e9f..2154cb1dd5f 100644 --- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/BinaryToMessageConverter.java +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/BinaryToMessageConverter.java @@ -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.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 @@ @ReadingConverter public class BinaryToMessageConverter implements Converter> { - private final WhiteListDeserializingConverter deserializingConverter = new WhiteListDeserializingConverter(); + private final AllowListDeserializingConverter deserializingConverter = new AllowListDeserializingConverter(); @Override public Message convert(Binary source) { @@ -43,9 +43,22 @@ public Message convert(Binary source) { * 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); } } diff --git a/src/nohttp/whitelist.lines b/src/nohttp/allowlist.lines similarity index 100% rename from src/nohttp/whitelist.lines rename to src/nohttp/allowlist.lines diff --git a/src/reference/asciidoc/transformer.adoc b/src/reference/asciidoc/transformer.adoc index 2c57d529f9d..c20d9b3f56d 100644 --- a/src/reference/asciidoc/transformer.adoc +++ b/src/reference/asciidoc/transformer.adoc @@ -131,11 +131,11 @@ The following example shows to use Spring's serializer and deserializer: + 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