This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1fc18da74fa480074df4b44ab7d0dbf1a34d7c84 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue May 12 07:57:40 2020 +0200 CAMEL-15050: Templating components - Variable map to be limited to body/headers --- .../dsl/FreemarkerComponentBuilderFactory.java | 18 ++++++++++++ .../org/apache/camel/util/ExchangeHelperTest.java | 25 ++++++++++++++-- .../endpoint/dsl/ChunkEndpointBuilderFactory.java | 34 ++++++++++++++++++++++ .../dsl/FreemarkerEndpointBuilderFactory.java | 34 ++++++++++++++++++++++ .../apache/camel/component/ResourceEndpoint.java | 20 +++++++++++++ .../org/apache/camel/support/ExchangeHelper.java | 34 +++++++++++++--------- 6 files changed, 148 insertions(+), 17 deletions(-) diff --git a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/FreemarkerComponentBuilderFactory.java b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/FreemarkerComponentBuilderFactory.java index f0236a0..f7212f9 100644 --- a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/FreemarkerComponentBuilderFactory.java +++ b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/FreemarkerComponentBuilderFactory.java @@ -49,6 +49,23 @@ public interface FreemarkerComponentBuilderFactory { extends ComponentBuilder<FreemarkerComponent> { /** + * Sets whether the context map should allow access to all details. By + * default only the message body and headers can be accessed. This + * option can be enabled for full access to the current Exchange and + * CamelContext. Doing so impose a potential security risk as this opens + * access to the full power of CamelContext API. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default FreemarkerComponentBuilder allowContextMapAll( + boolean allowContextMapAll) { + doSetProperty("allowContextMapAll", allowContextMapAll); + return this; + } + /** * Whether to allow to use resource template from header or not (default * false). Enabling this allows to specify dynamic templates via message * header. However this can be seen as a potential security @@ -130,6 +147,7 @@ public interface FreemarkerComponentBuilderFactory { String name, Object value) { switch (name) { + case "allowContextMapAll": ((FreemarkerComponent) component).setAllowContextMapAll((boolean) value); return true; case "allowTemplateFromHeader": ((FreemarkerComponent) component).setAllowTemplateFromHeader((boolean) value); return true; case "lazyStartProducer": ((FreemarkerComponent) component).setLazyStartProducer((boolean) value); return true; case "basicPropertyBinding": ((FreemarkerComponent) component).setBasicPropertyBinding((boolean) value); return true; diff --git a/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java index 4e2cb59..00f1ca5 100644 --- a/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/util/ExchangeHelperTest.java @@ -120,13 +120,32 @@ public class ExchangeHelperTest extends ContextTestSupport { } @Test + public void testPopulateVariableMapBodyAndHeaderOnly() throws Exception { + exchange.setPattern(ExchangePattern.InOut); + exchange.getOut().setBody("bar"); + exchange.getOut().setHeader("quote", "Camel rocks"); + + Map<String, Object> map = new HashMap<>(); + ExchangeHelper.populateVariableMap(exchange, map, false); + + assertEquals(2, map.size()); + assertNull(map.get("exchange")); + assertNull(map.get("in")); + assertNull(map.get("request")); + assertNull(map.get("out")); + assertNull(map.get("response")); + assertSame(exchange.getIn().getHeaders(), map.get("headers")); + assertSame(exchange.getIn().getBody(), map.get("body")); + assertNull(map.get("camelContext")); + } + @Test public void testPopulateVariableMap() throws Exception { exchange.setPattern(ExchangePattern.InOut); exchange.getOut().setBody("bar"); exchange.getOut().setHeader("quote", "Camel rocks"); Map<String, Object> map = new HashMap<>(); - ExchangeHelper.populateVariableMap(exchange, map); + ExchangeHelper.populateVariableMap(exchange, map, true); assertEquals(8, map.size()); assertSame(exchange, map.get("exchange")); @@ -145,7 +164,7 @@ public class ExchangeHelperTest extends ContextTestSupport { exchange.getOut().setBody("bar"); exchange.getOut().setHeader("quote", "Camel rocks"); - Map<?, ?> map = ExchangeHelper.createVariableMap(exchange); + Map<?, ?> map = ExchangeHelper.createVariableMap(exchange, true); assertEquals(8, map.size()); assertSame(exchange, map.get("exchange")); @@ -165,7 +184,7 @@ public class ExchangeHelperTest extends ContextTestSupport { exchange.getIn().setHeader("quote", "Camel rocks"); assertFalse(exchange.hasOut()); - Map<?, ?> map = ExchangeHelper.createVariableMap(exchange); + Map<?, ?> map = ExchangeHelper.createVariableMap(exchange, true); // there should still be 8 in the map assertEquals(8, map.size()); diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ChunkEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ChunkEndpointBuilderFactory.java index 9e1ba2e..bace03e 100644 --- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ChunkEndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ChunkEndpointBuilderFactory.java @@ -96,6 +96,40 @@ public interface ChunkEndpointBuilderFactory { return this; } /** + * Whether the context map is limited to only include the message body + * and headers (default). However access to the current Exchange and + * CamelContext can be enabled by turning this option off. Doing so + * impose a potential security risk as this opens access to the full + * power of CamelContext API. + * + * The option is a: <code>boolean</code> type. + * + * Default: true + * Group: producer + */ + default ChunkEndpointBuilder contextMapBodyAndHeadersOnly( + boolean contextMapBodyAndHeadersOnly) { + doSetProperty("contextMapBodyAndHeadersOnly", contextMapBodyAndHeadersOnly); + return this; + } + /** + * Whether the context map is limited to only include the message body + * and headers (default). However access to the current Exchange and + * CamelContext can be enabled by turning this option off. Doing so + * impose a potential security risk as this opens access to the full + * power of CamelContext API. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: true + * Group: producer + */ + default ChunkEndpointBuilder contextMapBodyAndHeadersOnly( + String contextMapBodyAndHeadersOnly) { + doSetProperty("contextMapBodyAndHeadersOnly", contextMapBodyAndHeadersOnly); + return this; + } + /** * Define the encoding of the body. * * The option is a: <code>java.lang.String</code> type. diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/FreemarkerEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/FreemarkerEndpointBuilderFactory.java index 54bfadf..af5defe 100644 --- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/FreemarkerEndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/FreemarkerEndpointBuilderFactory.java @@ -40,6 +40,40 @@ public interface FreemarkerEndpointBuilderFactory { return (AdvancedFreemarkerEndpointBuilder) this; } /** + * Sets whether the context map should allow access to all details. By + * default only the message body and headers can be accessed. This + * option can be enabled for full access to the current Exchange and + * CamelContext. Doing so impose a potential security risk as this opens + * access to the full power of CamelContext API. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default FreemarkerEndpointBuilder allowContextMapAll( + boolean allowContextMapAll) { + doSetProperty("allowContextMapAll", allowContextMapAll); + return this; + } + /** + * Sets whether the context map should allow access to all details. By + * default only the message body and headers can be accessed. This + * option can be enabled for full access to the current Exchange and + * CamelContext. Doing so impose a potential security risk as this opens + * access to the full power of CamelContext API. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default FreemarkerEndpointBuilder allowContextMapAll( + String allowContextMapAll) { + doSetProperty("allowContextMapAll", allowContextMapAll); + return this; + } + /** * Whether to allow to use resource template from header or not (default * false). Enabling this allows to specify dynamic templates via message * header. However this can be seen as a potential security diff --git a/core/camel-support/src/main/java/org/apache/camel/component/ResourceEndpoint.java b/core/camel-support/src/main/java/org/apache/camel/component/ResourceEndpoint.java index a684815..beeeef7 100644 --- a/core/camel-support/src/main/java/org/apache/camel/component/ResourceEndpoint.java +++ b/core/camel-support/src/main/java/org/apache/camel/component/ResourceEndpoint.java @@ -54,6 +54,11 @@ public abstract class ResourceEndpoint extends ProcessorEndpoint implements Mana private String resourceUri; @UriParam(defaultValue = "false", description = "Sets whether to use resource content cache or not") private boolean contentCache; + @UriParam(defaultValue = "false", description = "Sets whether the context map should allow access to all details." + + " By default only the message body and headers can be accessed." + + " This option can be enabled for full access to the current Exchange and CamelContext." + + " Doing so impose a potential security risk as this opens access to the full power of CamelContext API.") + private boolean allowContextMapAll; public ResourceEndpoint() { } @@ -124,6 +129,21 @@ public abstract class ResourceEndpoint extends ProcessorEndpoint implements Mana return buffer == null; } + @ManagedAttribute(description = "Whether the context map is limited to only include the message body and headers") + public boolean isAllowContextMapAll() { + return allowContextMapAll; + } + + /** + * Sets whether the context map should allow access to all details. + * By default only the message body and headers can be accessed. + * This option can be enabled for full access to the current Exchange and CamelContext. + * Doing so impose a potential security risk as this opens access to the full power of CamelContext API. + */ + public void setAllowContextMapAll(boolean allowContextMapAll) { + this.allowContextMapAll = allowContextMapAll; + } + @Override @ManagedAttribute(description = "Camel context ID") public String getCamelId() { diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java index 0bf9076..1bdf539 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java @@ -457,11 +457,13 @@ public final class ExchangeHelper { * Creates a Map of the variables which are made available to a script or template * * @param exchange the exchange to make available + * @param allowContextMapAll whether to allow access to all context map or not + * (prefer to use false due to security reasons preferred to only allow access to body/headers) * @return a Map populated with the require variables */ - public static Map<String, Object> createVariableMap(Exchange exchange) { + public static Map<String, Object> createVariableMap(Exchange exchange, boolean allowContextMapAll) { Map<String, Object> answer = new HashMap<>(); - populateVariableMap(exchange, answer); + populateVariableMap(exchange, answer, allowContextMapAll); return answer; } @@ -470,23 +472,27 @@ public final class ExchangeHelper { * * @param exchange the exchange to make available * @param map the map to populate + * @param allowContextMapAll whether to allow access to all context map or not + * (prefer to use false due to security reasons preferred to only allow access to body/headers) */ - public static void populateVariableMap(Exchange exchange, Map<String, Object> map) { - map.put("exchange", exchange); + public static void populateVariableMap(Exchange exchange, Map<String, Object> map, boolean allowContextMapAll) { Message in = exchange.getIn(); - map.put("in", in); - map.put("request", in); map.put("headers", in.getHeaders()); map.put("body", in.getBody()); - if (isOutCapable(exchange)) { - // if we are out capable then set out and response as well - // however only grab OUT if it exists, otherwise reuse IN - // this prevents side effects to alter the Exchange if we force creating an OUT message - Message msg = exchange.getMessage(); - map.put("out", msg); - map.put("response", msg); + if (allowContextMapAll) { + map.put("in", in); + map.put("request", in); + map.put("exchange", exchange); + if (isOutCapable(exchange)) { + // if we are out capable then set out and response as well + // however only grab OUT if it exists, otherwise reuse IN + // this prevents side effects to alter the Exchange if we force creating an OUT message + Message msg = exchange.getMessage(); + map.put("out", msg); + map.put("response", msg); + } + map.put("camelContext", exchange.getContext()); } - map.put("camelContext", exchange.getContext()); } /**