davsclaus commented on code in PR #27721:
URL: https://github.com/apache/camel/pull/27721#discussion_r4269515991
##########
components/camel-chunk/src/main/docs/chunk-component.adoc:
##########
@@ -261,3 +261,15 @@ Thanks for the order of {$headers.item}.
Regards Camel Riders Bookstore
{$body}
----------------------------------------------
+
+== Security
+
+The Chunk engine renders the template provided by the route author. Message
data (the body, headers and
+variables) that is printed with a direct tag such as `{$body}` or
`{$headers.name}` is rendered literally, so
+template tags that appear inside that data are printed verbatim and not
evaluated.
+
+Chunk does, however, re-parse any string it produces while rendering. The
output of a filter (`{$body|trim}`),
+a string property of a bean body (`{$body.name}`, `{$exception.message}`) and
string items bound by a
+`{% loop %}` are parsed as template code. Do not pass untrusted message data
through Chunk filters, bean
+properties or loops, and do not enable `allowTemplateFromHeader` for messages
from untrusted senders. Escape
Review Comment:
"Escape untrusted values in the route before the template" does not say how,
and Chunk has no escape for tags inside data. Either give a concrete example
(such as removing or replacing `{` and `}` in the value with a
`setHeader`/`transform` step before the `chunk` endpoint), or drop the sentence.
##########
components/camel-chunk/src/main/java/org/apache/camel/component/chunk/ChunkEndpoint.java:
##########
@@ -134,6 +145,68 @@ protected void onExchange(Exchange exchange) throws
Exception {
}
}
+ /**
+ * Neutralizes message data so the Chunk engine does not parse and expand
template tags present inside the data
+ * itself when it is printed with a direct {@code {$tag}}. A String (or
other {@link CharSequence}) value is wrapped
+ * as a literal Chunk snippet only when it actually contains Chunk tags
(as reported by Chunk's own parser via
+ * {@link Snippet#isSimple()}); tag-free values are left as-is so Chunk's
string filters (for example {@code slice},
+ * {@code get}, {@code join}) keep their existing behaviour. Nested {@link
Map}, {@link Collection} and array values
+ * (message headers, variables, multi-value headers, unmarshalled JSON,
...) are copied and processed recursively,
+ * preserving a case-insensitive headers map. Other value types are left
unchanged.
+ * <p/>
+ * This does not cover every case: Chunk re-parses any string it produces
while rendering, so the output of a filter
+ * ({@code {$body|trim}}), a string property of a bean body ({@code
{$body.name}}, {@code {$exception.message}}) and
+ * string items produced inside a {@code {% loop %}} are still parsed as
template code. Untrusted data must not be
+ * passed through Chunk filters, bean properties or loops.
+ */
+ @SuppressWarnings("unchecked")
+ private static Object toLiteralValue(Object value, HeadersMapFactory
factory) {
+ if (value instanceof String) {
+ return toLiteralString((String) value);
+ }
+ if (value instanceof CharSequence) {
+ // StringBuilder/StringBuffer and other CharSequences are
otherwise stringified and re-parsed by Chunk
+ return toLiteralString(value.toString());
+ }
+ if (value instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>) value;
+ Map<String, Object> copy = factory.isInstanceOf((Map<String,
Object>) value)
+ ? factory.newMap() : new LinkedHashMap<>();
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
+ copy.put(String.valueOf(entry.getKey()),
toLiteralValue(entry.getValue(), factory));
+ }
+ return copy;
+ }
+ if (value instanceof Collection) {
Review Comment:
Minor: this also turns a `Set` into a `List`. With a `Set` body of `x`, `y`,
`{$body}` printed `[x, y]` before and now prints Chunk's `[LIST - Use a loop
construct ...]` placeholder, and `{$body|join(-)}` gives `x-y` instead of `[x,
y]`. Loops are unchanged. Converting is the safer choice, since the old
`toString()` path re-parsed tags inside the items, so I would keep it. A short
mention in the upgrade note would cover it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]