From 2e775ce96390390e1dd645c4569b47e42005958f Mon Sep 17 00:00:00 2001 From: Andrea Cosentino Date: Fri, 31 Jul 2026 23:15:31 +0200 Subject: [PATCH] CAMEL-24294: enforce the typeFilters allow-list in the SnakeYAML TagInspector SnakeYAMLDataFormat's TrustedTagInspector.isGlobalTagAllowed() returned true unconditionally, so the SnakeYAML 2.x TagInspector layer was effectively disabled and the typeFilters allow-list was enforced only by the getClassForName constructor override. Make the inspector consult the same allowTypeFilter(...) check so both layers enforce the configured filters. When typeFilters/unmarshalType is configured, a disallowed global tag is now rejected earlier (during composing) as a ComposerException, instead of the previous ConstructorException caused by an IllegalArgumentException from getClassForName. The set of accepted types is unchanged; the security tests and an upgrade-guide note are updated accordingly. Routes without typeFilters are unaffected. Co-authored-by: Claude Opus 4.8 --- .../snakeyaml/SnakeYAMLDataFormat.java | 4 +++- .../snakeyaml/SnakeYAMLTypeFilterHelper.java | 17 +++++++++-------- .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc | 10 ++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java index 21074bba843d6..34474b06bd18b 100644 --- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java +++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java @@ -348,7 +348,9 @@ protected Class getClassForName(String name) throws ClassNotFoundException { final class TrustedTagInspector implements TagInspector { @Override public boolean isGlobalTagAllowed(Tag tag) { - return true; + // consult the same typeFilters allow-list as getClassForName, so the SnakeYAML 2.x TagInspector + // layer actually enforces the configured filters instead of allowing every global tag (CAMEL-24294) + return allowTypeFilter(tag.getClassName()); } } } diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java index cb2b6e4e9c017..9ed02ad158bc4 100644 --- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java +++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java @@ -21,6 +21,7 @@ import org.apache.camel.component.snakeyaml.model.RexPojo; import org.apache.camel.component.snakeyaml.model.TestPojo; import org.apache.camel.component.snakeyaml.model.UnsafePojo; +import org.yaml.snakeyaml.composer.ComposerException; import org.yaml.snakeyaml.constructor.ConstructorException; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -57,10 +58,11 @@ static void testTypeConstructor(ProducerTemplate template) { "!!org.apache.camel.component.snakeyaml.model.UnsafePojo {name: Camel}"), "As SnakeYAML filters class is can unmarshall, UnsafePojo should not be allowed"); - // Wrapped by SnakeYAML - assertTrue(ex.getCause() instanceof ConstructorException); - // Thrown by SnakeYAMLDataFormat - assertTrue(ex.getCause().getCause() instanceof IllegalArgumentException); + // Rejected by the SnakeYAML TagInspector allow-list during composing (CAMEL-24294), before + // getClassForName would run - so the failure is a ComposerException, not the previous + // ConstructorException -> IllegalArgumentException chain. + assertTrue(ex.getCause() instanceof ComposerException); + assertTrue(ex.getCause().getMessage().contains("UnsafePojo")); } static void testTypeConstructorFromDefinition(ProducerTemplate template) { @@ -88,10 +90,9 @@ static void testTypeConstructorFromDefinition(ProducerTemplate template) { "!!org.apache.camel.component.snakeyaml.model.UnsafePojo {name: Camel}"), "As SnakeYAML filters class is can unmarshall, UnsafePojo should not be allowed"); - // Wrapped by SnakeYAML - assertTrue(ex.getCause() instanceof ConstructorException); - // Thrown by SnakeYAMLDataFormat - assertTrue(ex.getCause().getCause() instanceof IllegalArgumentException); + // Rejected by the SnakeYAML TagInspector allow-list during composing (CAMEL-24294) + assertTrue(ex.getCause() instanceof ComposerException); + assertTrue(ex.getCause().getMessage().contains("UnsafePojo")); } static void testAllowAllConstructor(ProducerTemplate template) { diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc index aa4417a1e2a62..61710a08ee8c9 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc @@ -1421,3 +1421,13 @@ entry name could escape the intended directory (Tar Slip / Zip Slip). data format and the iterator/splitter modes. The full, unmodified entry name remains available so routes that intentionally recreate the archive's directory structure keep working — read it from `CamelTarFileEntryName` for tar and from `zipFileName` for zip instead of `CamelFileName`. + +=== camel-snakeyaml - typeFilters are now also enforced by the SnakeYAML TagInspector + +When `typeFilters` (or `unmarshalType`) is configured, the allow-list is now also enforced by the +SnakeYAML 2.x `TagInspector` layer, not only by the `getClassForName` constructor override. A YAML +document that references a disallowed global tag is therefore rejected earlier, during composing, and +surfaces as an `org.yaml.snakeyaml.composer.ComposerException` (`"Global tag is not allowed: ..."`) +instead of the previous `ConstructorException` caused by an `IllegalArgumentException`. The set of +accepted types is unchanged; only the exception raised for a rejected type differs. Routes that do not +configure `typeFilters` are unaffected.