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]

Reply via email to