Upgrade to SnakeYAML 2.0

This commit raises the SnakeYAML baseline version to 2.0.
While most Spring applications are not affected by CVE-2022-1471,
upgrading this version should prevent automated tools from raising this
as a security issue. Such tools usually do not understand that YAML
parsing in Spring is about reading configuration, not parsing untrusted
content.

Closes gh-30048
This commit is contained in:
Andrey Somov 2023-05-22 14:31:27 +02:00 committed by Brian Clozel
parent 96a429a561
commit 097758baf3
3 changed files with 14 additions and 23 deletions

View File

@ -144,6 +144,6 @@ dependencies {
api("org.webjars:webjars-locator-core:0.52")
api("org.xmlunit:xmlunit-assertj:2.9.1")
api("org.xmlunit:xmlunit-matchers:2.9.1")
api("org.yaml:snakeyaml:1.33")
api("org.yaml:snakeyaml:2.0")
}
}

View File

@ -34,6 +34,8 @@ import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.inspector.TagInspector;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.reader.UnicodeReader;
import org.yaml.snakeyaml.representer.Representer;
@ -184,8 +186,9 @@ public abstract class YamlProcessor {
protected Yaml createYaml() {
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setAllowDuplicateKeys(false);
loaderOptions.setTagInspector(new SupportedTagInspector());
DumperOptions dumperOptions = new DumperOptions();
return new Yaml(new FilteringConstructor(loaderOptions), new Representer(dumperOptions),
return new Yaml(new Constructor(loaderOptions), new Representer(dumperOptions),
dumperOptions, loaderOptions);
}
@ -425,23 +428,11 @@ public abstract class YamlProcessor {
FIRST_FOUND
}
/**
* {@link Constructor} that supports filtering of unsupported types.
* <p>If an unsupported type is encountered in a YAML document, an
* {@link IllegalStateException} will be thrown from {@link #getClassForName}.
*/
private class FilteringConstructor extends Constructor {
FilteringConstructor(LoaderOptions loaderOptions) {
super(loaderOptions);
}
private class SupportedTagInspector implements TagInspector {
@Override
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
Assert.state(YamlProcessor.this.supportedTypes.contains(name),
() -> "Unsupported type encountered in YAML document: " + name);
return super.getClassForName(name);
public boolean isGlobalTagAllowed(Tag tag) {
return supportedTypes.contains(tag.getClassName());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -24,7 +24,7 @@ import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.constructor.ConstructorException;
import org.yaml.snakeyaml.composer.ComposerException;
import org.yaml.snakeyaml.parser.ParserException;
import org.yaml.snakeyaml.scanner.ScannerException;
@ -156,9 +156,9 @@ class YamlProcessorTests {
void customTypeNotSupportedByDefault() throws Exception {
URL url = new URL("https://localhost:9000/");
setYaml("value: !!java.net.URL [\"" + url + "\"]");
assertThatExceptionOfType(ConstructorException.class)
assertThatExceptionOfType(ComposerException.class)
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("Unsupported type encountered in YAML document: java.net.URL");
.withMessageContaining("Global tag is not allowed: tag:yaml.org,2002:java.net.URL");
}
@Test
@ -180,9 +180,9 @@ class YamlProcessorTests {
setYaml("value: !!java.net.URL [\"https://localhost:9000/\"]");
assertThatExceptionOfType(ConstructorException.class)
assertThatExceptionOfType(ComposerException.class)
.isThrownBy(() -> this.processor.process((properties, map) -> {}))
.withMessageContaining("Unsupported type encountered in YAML document: java.net.URL");
.withMessageContaining("Global tag is not allowed: tag:yaml.org,2002:java.net.URL");
}
private void setYaml(String yaml) {