This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch ex
in repository https://gitbox.apache.org/repos/asf/camel.git

commit b0a1501974246f137138680e13466ebc7a2d1bd3
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Apr 13 15:54:53 2026 +0200

    CAMEL-23315: camel-exec - Add option to turn on|off control headers for 
camel-exec to make it more restricted by default.
---
 .../org/apache/camel/catalog/components/exec.json  |  26 +--
 .../component/exec/ExecComponentConfigurer.java    |  24 +++
 .../component/exec/ExecEndpointConfigurer.java     |   8 +-
 .../component/exec/ExecEndpointUriFactory.java     |   3 +-
 .../org/apache/camel/component/exec/exec.json      |  26 +--
 .../apache/camel/component/exec/ExecComponent.java |  87 +++++++++-
 .../apache/camel/component/exec/ExecEndpoint.java  |  34 ++--
 .../component/exec/impl/DefaultExecBinding.java    |  32 ++--
 .../component/exec/DefaultExecBindingTest.java     |   4 +-
 .../exec/ExecJavaProcessRecipientListTest.java     |   3 +
 .../camel/component/exec/ExecJavaProcessTest.java  |   2 +-
 .../camel/component/exec/ExecOutFileTest.java      |   6 +-
 .../camel/component/exec/ExecProducerTest.java     |  14 +-
 .../component/exec/exec-mock-executor-context.xml  |   5 +
 .../ROOT/pages/camel-4x-upgrade-guide-4_20.adoc    |   7 +
 .../component/dsl/ExecComponentBuilderFactory.java |  96 +++++++++++
 .../endpoint/dsl/ExecEndpointBuilderFactory.java   | 176 +++++++++++++--------
 17 files changed, 425 insertions(+), 128 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/exec.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/exec.json
index 33f90104fe41..0b2fc3bc98a1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/exec.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/exec.json
@@ -25,7 +25,12 @@
   },
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "timeout": { "index": 1, "kind": "property", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
+    "workingDir": { "index": 2, "kind": "property", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
+    "allowControlHeaders": { "index": 3, "kind": "property", "displayName": 
"Allow Control Headers", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to allow to use Camel headers or not (default false). Enabling this 
allows to specify dynamic command line arguments via message header. However 
this can be seen as a potential securi [...]
+    "autowiredEnabled": { "index": 4, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "binding": { "index": 5, "kind": "property", "displayName": "Binding", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecBinding for advanced use-cases." },
+    "commandExecutor": { "index": 6, "kind": "property", "displayName": 
"Command Executor", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecCommandExecutor that customizes the command 
execution. The default command executor utilizes the commons-exec library, 
which adds a shut [...]
   },
   "headers": {
     "CamelExecCommandExecutable": { "index": 0, "kind": "header", 
"displayName": "", "group": "in", "label": "in", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of the system command that will be 
executed. Overrides executable in the URI.", "constantName": 
"org.apache.camel.component.exec.ExecBinding#EXEC_COMMAND_EXECUTABLE" },
@@ -42,14 +47,15 @@
   "properties": {
     "executable": { "index": 0, "kind": "path", "displayName": "Executable", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Sets the executable to be 
executed. The executable must not be empty or null." },
     "args": { "index": 1, "kind": "parameter", "displayName": "Args", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The arguments may be one or many whitespace-separated tokens." 
},
-    "binding": { "index": 2, "kind": "parameter", "displayName": "Binding", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "A reference to a 
org.apache.commons.exec.ExecBinding in the Registry." },
-    "commandExecutor": { "index": 3, "kind": "parameter", "displayName": 
"Command Executor", "group": "producer", "label": "", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "A reference to a 
org.apache.commons.exec.ExecCommandExecutor in the Registry that customizes the 
command execution. The default command executor utilizes the commons-exec 
library, which a [...]
-    "commandLogLevel": { "index": 4, "kind": "parameter", "displayName": 
"Command Log Level", "group": "producer", "label": "", "required": false, 
"type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", 
"DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "DEBUG", "description": "Logging level 
to be used for commands during execution. The default value is DEBUG. Possible 
values are TRACE, DEBUG, INFO, [...]
-    "exitValues": { "index": 5, "kind": "parameter", "displayName": "Exit 
Values", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The exit values of successful executions. If 
the process exits with another value, an exception is raised. Comma-separated 
list of exit values. And empty list (the default) sets no expected exit values 
and disables the check." },
-    "outFile": { "index": 6, "kind": "parameter", "displayName": "Out File", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The name of a file, created by the executable, 
that should be considered as its output. If no outFile is set, the standard 
output (stdout) of the executable will be used instead." },
-    "timeout": { "index": 7, "kind": "parameter", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "duration", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
-    "useStderrOnEmptyStdout": { "index": 8, "kind": "parameter", 
"displayName": "Use Stderr On Empty Stdout", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "A boolean indicating that when stdout is empty, this component 
will populate the Camel Message Body with stderr. This behavior is disabled 
(false) by default." },
-    "workingDir": { "index": 9, "kind": "parameter", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
-    "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "commandLogLevel": { "index": 2, "kind": "parameter", "displayName": 
"Command Log Level", "group": "producer", "label": "", "required": false, 
"type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", 
"DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "DEBUG", "description": "Logging level 
to be used for commands during execution. The default value is DEBUG. Possible 
values are TRACE, DEBUG, INFO, [...]
+    "exitValues": { "index": 3, "kind": "parameter", "displayName": "Exit 
Values", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The exit values of successful executions. If 
the process exits with another value, an exception is raised. Comma-separated 
list of exit values. And empty list (the default) sets no expected exit values 
and disables the check." },
+    "outFile": { "index": 4, "kind": "parameter", "displayName": "Out File", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The name of a file, created by the executable, 
that should be considered as its output. If no outFile is set, the standard 
output (stdout) of the executable will be used instead." },
+    "timeout": { "index": 5, "kind": "parameter", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
+    "useStderrOnEmptyStdout": { "index": 6, "kind": "parameter", 
"displayName": "Use Stderr On Empty Stdout", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "A boolean indicating that when stdout is empty, this component 
will populate the Camel Message Body with stderr. This behavior is disabled 
(false) by default." },
+    "workingDir": { "index": 7, "kind": "parameter", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
+    "lazyStartProducer": { "index": 8, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "allowControlHeaders": { "index": 9, "kind": "parameter", "displayName": 
"Allow Control Headers", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to allow to use Camel headers or not (default false). Enabling this 
allows to specify dynamic command line arguments via message header. However 
this can be seen as a potential secur [...]
+    "binding": { "index": 10, "kind": "parameter", "displayName": "Binding", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecBinding for advanced use-cases." },
+    "commandExecutor": { "index": 11, "kind": "parameter", "displayName": 
"Command Executor", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecCommandExecutor that customizes the command 
execution. The default command executor utilizes the commons-exec library, 
which adds a sh [...]
   }
 }
diff --git 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecComponentConfigurer.java
 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecComponentConfigurer.java
index 1ef790cbab80..7cda185a8135 100644
--- 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecComponentConfigurer.java
+++ 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecComponentConfigurer.java
@@ -23,10 +23,18 @@ public class ExecComponentConfigurer extends 
PropertyConfigurerSupport implement
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         ExecComponent target = (ExecComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": 
target.setAllowControlHeaders(property(camelContext, boolean.class, value)); 
return true;
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "binding": target.setBinding(property(camelContext, 
org.apache.camel.component.exec.ExecBinding.class, value)); return true;
+        case "commandexecutor":
+        case "commandExecutor": 
target.setCommandExecutor(property(camelContext, 
org.apache.camel.component.exec.ExecCommandExecutor.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "timeout": target.setTimeout(property(camelContext, long.class, 
value)); return true;
+        case "workingdir":
+        case "workingDir": target.setWorkingDir(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -34,10 +42,18 @@ public class ExecComponentConfigurer extends 
PropertyConfigurerSupport implement
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": return boolean.class;
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "binding": return 
org.apache.camel.component.exec.ExecBinding.class;
+        case "commandexecutor":
+        case "commandExecutor": return 
org.apache.camel.component.exec.ExecCommandExecutor.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
+        case "timeout": return long.class;
+        case "workingdir":
+        case "workingDir": return java.lang.String.class;
         default: return null;
         }
     }
@@ -46,10 +62,18 @@ public class ExecComponentConfigurer extends 
PropertyConfigurerSupport implement
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         ExecComponent target = (ExecComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": return target.isAllowControlHeaders();
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "binding": return target.getBinding();
+        case "commandexecutor":
+        case "commandExecutor": return target.getCommandExecutor();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "timeout": return target.getTimeout();
+        case "workingdir":
+        case "workingDir": return target.getWorkingDir();
         default: return null;
         }
     }
diff --git 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointConfigurer.java
 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointConfigurer.java
index 30aeff3160e2..0ef33deb4fdd 100644
--- 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointConfigurer.java
+++ 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointConfigurer.java
@@ -23,6 +23,8 @@ public class ExecEndpointConfigurer extends 
PropertyConfigurerSupport implements
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         ExecEndpoint target = (ExecEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": 
target.setAllowControlHeaders(property(camelContext, boolean.class, value)); 
return true;
         case "args": target.setArgs(property(camelContext, 
java.lang.String.class, value)); return true;
         case "binding": target.setBinding(property(camelContext, 
org.apache.camel.component.exec.ExecBinding.class, value)); return true;
         case "commandexecutor":
@@ -35,7 +37,7 @@ public class ExecEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         case "outfile":
         case "outFile": target.setOutFile(property(camelContext, 
java.lang.String.class, value)); return true;
-        case "timeout": target.setTimeout(property(camelContext, 
java.time.Duration.class, value).toMillis()); return true;
+        case "timeout": target.setTimeout(property(camelContext, long.class, 
value)); return true;
         case "usestderronemptystdout":
         case "useStderrOnEmptyStdout": 
target.setUseStderrOnEmptyStdout(property(camelContext, boolean.class, value)); 
return true;
         case "workingdir":
@@ -47,6 +49,8 @@ public class ExecEndpointConfigurer extends 
PropertyConfigurerSupport implements
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": return boolean.class;
         case "args": return java.lang.String.class;
         case "binding": return 
org.apache.camel.component.exec.ExecBinding.class;
         case "commandexecutor":
@@ -72,6 +76,8 @@ public class ExecEndpointConfigurer extends 
PropertyConfigurerSupport implements
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         ExecEndpoint target = (ExecEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowcontrolheaders":
+        case "allowControlHeaders": return target.isAllowControlHeaders();
         case "args": return target.getArgs();
         case "binding": return target.getBinding();
         case "commandexecutor":
diff --git 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointUriFactory.java
 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointUriFactory.java
index 2659656b7190..e09a4effb712 100644
--- 
a/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointUriFactory.java
+++ 
b/components/camel-exec/src/generated/java/org/apache/camel/component/exec/ExecEndpointUriFactory.java
@@ -23,7 +23,8 @@ public class ExecEndpointUriFactory extends 
org.apache.camel.support.component.E
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(11);
+        Set<String> props = new HashSet<>(12);
+        props.add("allowControlHeaders");
         props.add("args");
         props.add("binding");
         props.add("commandExecutor");
diff --git 
a/components/camel-exec/src/generated/resources/META-INF/org/apache/camel/component/exec/exec.json
 
b/components/camel-exec/src/generated/resources/META-INF/org/apache/camel/component/exec/exec.json
index 33f90104fe41..0b2fc3bc98a1 100644
--- 
a/components/camel-exec/src/generated/resources/META-INF/org/apache/camel/component/exec/exec.json
+++ 
b/components/camel-exec/src/generated/resources/META-INF/org/apache/camel/component/exec/exec.json
@@ -25,7 +25,12 @@
   },
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "timeout": { "index": 1, "kind": "property", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
+    "workingDir": { "index": 2, "kind": "property", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
+    "allowControlHeaders": { "index": 3, "kind": "property", "displayName": 
"Allow Control Headers", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to allow to use Camel headers or not (default false). Enabling this 
allows to specify dynamic command line arguments via message header. However 
this can be seen as a potential securi [...]
+    "autowiredEnabled": { "index": 4, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "binding": { "index": 5, "kind": "property", "displayName": "Binding", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecBinding for advanced use-cases." },
+    "commandExecutor": { "index": 6, "kind": "property", "displayName": 
"Command Executor", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecCommandExecutor that customizes the command 
execution. The default command executor utilizes the commons-exec library, 
which adds a shut [...]
   },
   "headers": {
     "CamelExecCommandExecutable": { "index": 0, "kind": "header", 
"displayName": "", "group": "in", "label": "in", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of the system command that will be 
executed. Overrides executable in the URI.", "constantName": 
"org.apache.camel.component.exec.ExecBinding#EXEC_COMMAND_EXECUTABLE" },
@@ -42,14 +47,15 @@
   "properties": {
     "executable": { "index": 0, "kind": "path", "displayName": "Executable", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Sets the executable to be 
executed. The executable must not be empty or null." },
     "args": { "index": 1, "kind": "parameter", "displayName": "Args", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The arguments may be one or many whitespace-separated tokens." 
},
-    "binding": { "index": 2, "kind": "parameter", "displayName": "Binding", 
"group": "producer", "label": "", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "A reference to a 
org.apache.commons.exec.ExecBinding in the Registry." },
-    "commandExecutor": { "index": 3, "kind": "parameter", "displayName": 
"Command Executor", "group": "producer", "label": "", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "A reference to a 
org.apache.commons.exec.ExecCommandExecutor in the Registry that customizes the 
command execution. The default command executor utilizes the commons-exec 
library, which a [...]
-    "commandLogLevel": { "index": 4, "kind": "parameter", "displayName": 
"Command Log Level", "group": "producer", "label": "", "required": false, 
"type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", 
"DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "DEBUG", "description": "Logging level 
to be used for commands during execution. The default value is DEBUG. Possible 
values are TRACE, DEBUG, INFO, [...]
-    "exitValues": { "index": 5, "kind": "parameter", "displayName": "Exit 
Values", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The exit values of successful executions. If 
the process exits with another value, an exception is raised. Comma-separated 
list of exit values. And empty list (the default) sets no expected exit values 
and disables the check." },
-    "outFile": { "index": 6, "kind": "parameter", "displayName": "Out File", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The name of a file, created by the executable, 
that should be considered as its output. If no outFile is set, the standard 
output (stdout) of the executable will be used instead." },
-    "timeout": { "index": 7, "kind": "parameter", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "duration", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
-    "useStderrOnEmptyStdout": { "index": 8, "kind": "parameter", 
"displayName": "Use Stderr On Empty Stdout", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "A boolean indicating that when stdout is empty, this component 
will populate the Camel Message Body with stderr. This behavior is disabled 
(false) by default." },
-    "workingDir": { "index": 9, "kind": "parameter", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
-    "lazyStartProducer": { "index": 10, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "commandLogLevel": { "index": 2, "kind": "parameter", "displayName": 
"Command Log Level", "group": "producer", "label": "", "required": false, 
"type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", 
"DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "DEBUG", "description": "Logging level 
to be used for commands during execution. The default value is DEBUG. Possible 
values are TRACE, DEBUG, INFO, [...]
+    "exitValues": { "index": 3, "kind": "parameter", "displayName": "Exit 
Values", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The exit values of successful executions. If 
the process exits with another value, an exception is raised. Comma-separated 
list of exit values. And empty list (the default) sets no expected exit values 
and disables the check." },
+    "outFile": { "index": 4, "kind": "parameter", "displayName": "Out File", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The name of a file, created by the executable, 
that should be considered as its output. If no outFile is set, the standard 
output (stdout) of the executable will be used instead." },
+    "timeout": { "index": 5, "kind": "parameter", "displayName": "Timeout", 
"group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The timeout, in milliseconds, after which the executable should 
be terminated. If execution has not completed within the timeout, the component 
will send a termination request." },
+    "useStderrOnEmptyStdout": { "index": 6, "kind": "parameter", 
"displayName": "Use Stderr On Empty Stdout", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "A boolean indicating that when stdout is empty, this component 
will populate the Camel Message Body with stderr. This behavior is disabled 
(false) by default." },
+    "workingDir": { "index": 7, "kind": "parameter", "displayName": "Working 
Dir", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "The directory in which the command should be 
executed. If null, the working directory of the current process will be used." 
},
+    "lazyStartProducer": { "index": 8, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
+    "allowControlHeaders": { "index": 9, "kind": "parameter", "displayName": 
"Allow Control Headers", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to allow to use Camel headers or not (default false). Enabling this 
allows to specify dynamic command line arguments via message header. However 
this can be seen as a potential secur [...]
+    "binding": { "index": 10, "kind": "parameter", "displayName": "Binding", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.exec.ExecBinding", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecBinding for advanced use-cases." },
+    "commandExecutor": { "index": 11, "kind": "parameter", "displayName": 
"Command Executor", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.exec.ExecCommandExecutor", "deprecated": false, 
"autowired": false, "secret": false, "description": "To use a custom 
org.apache.commons.exec.ExecCommandExecutor that customizes the command 
execution. The default command executor utilizes the commons-exec library, 
which adds a sh [...]
   }
 }
diff --git 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecComponent.java
 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecComponent.java
index cec200384584..dc1fb8058ec6 100644
--- 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecComponent.java
+++ 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecComponent.java
@@ -17,12 +17,17 @@
 package org.apache.camel.component.exec;
 
 import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
+import org.apache.camel.component.exec.impl.DefaultExecBinding;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 
+import static org.apache.camel.component.exec.ExecEndpoint.NO_TIMEOUT;
+
 /**
  * Represents the component that manages {@link ExecEndpoint}. With the 
component it is possible to execute system
  * commands.
@@ -30,14 +35,94 @@ import org.apache.camel.support.DefaultComponent;
 @Component("exec")
 public class ExecComponent extends DefaultComponent {
 
+    @Metadata
+    private String workingDir;
+    @Metadata(label = "advanced")
+    private boolean allowControlHeaders;
+    @Metadata(label = "advanced")
+    private ExecCommandExecutor commandExecutor;
+    @Metadata(label = "advanced")
+    private ExecBinding binding = new DefaultExecBinding();
+    @Metadata
+    private long timeout = NO_TIMEOUT;
+
     public ExecComponent() {
     }
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
         ExecEndpoint endpoint = new ExecEndpoint(uri, this);
+        endpoint.setWorkingDir(workingDir);
+        endpoint.setAllowControlHeaders(allowControlHeaders);
+        endpoint.setCommandExecutor(commandExecutor);
+        endpoint.setBinding(binding);
+        endpoint.setTimeout(timeout);
         setProperties(endpoint, parameters);
-        endpoint.setExecutable(URLDecoder.decode(remaining, "UTF-8"));
+        endpoint.setExecutable(URLDecoder.decode(remaining, 
StandardCharsets.UTF_8));
         return endpoint;
     }
+
+    public String getWorkingDir() {
+        return workingDir;
+    }
+
+    /**
+     * The directory in which the command should be executed. If null, the 
working directory of the current process will
+     * be used.
+     */
+    public void setWorkingDir(String workingDir) {
+        this.workingDir = workingDir;
+    }
+
+    public ExecCommandExecutor getCommandExecutor() {
+        return commandExecutor;
+    }
+
+    /**
+     * To use a custom org.apache.commons.exec.ExecCommandExecutor that 
customizes the command execution. The default
+     * command executor utilizes the commons-exec library, which adds a 
shutdown hook for every executed command.
+     */
+    public void setCommandExecutor(ExecCommandExecutor commandExecutor) {
+        this.commandExecutor = commandExecutor;
+    }
+
+    public ExecBinding getBinding() {
+        return binding;
+    }
+
+    /**
+     * To use a custom org.apache.commons.exec.ExecBinding for advanced 
use-cases.
+     */
+    public void setBinding(ExecBinding binding) {
+        this.binding = binding;
+    }
+
+    public boolean isAllowControlHeaders() {
+        return allowControlHeaders;
+    }
+
+    /**
+     * Whether to allow to use Camel headers or not (default false). Enabling 
this allows to specify dynamic command
+     * line arguments via message header. However this can be seen as a 
potential security vulnerability if the header
+     * is coming from a malicious user, so use this with care.
+     */
+    public void setAllowControlHeaders(boolean allowControlHeaders) {
+        this.allowControlHeaders = allowControlHeaders;
+    }
+
+    public long getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * The timeout, in milliseconds, after which the executable should be 
terminated. If execution has not completed
+     * within the timeout, the component will send a termination request.
+     */
+    public void setTimeout(long timeout) {
+        if (timeout <= 0) {
+            throw new IllegalArgumentException("The timeout must be a positive 
long!");
+        }
+        this.timeout = timeout;
+    }
+
 }
diff --git 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
index 8f2ddfebe9e2..dbe3c6edc276 100644
--- 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
+++ 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
@@ -21,13 +21,11 @@ import org.apache.camel.Consumer;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
-import org.apache.camel.component.exec.impl.DefaultExecBinding;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.DefaultEndpoint;
-import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -49,25 +47,25 @@ public class ExecEndpoint extends DefaultEndpoint {
     private String args;
     @UriParam
     private String workingDir;
-    @UriParam(javaType = "java.time.Duration")
+    @UriParam
     private long timeout;
     @UriParam
     private String exitValues;
     @UriParam
     private String outFile;
-    @UriParam
+    @UriParam(label = "advanced")
     private ExecCommandExecutor commandExecutor;
-    @UriParam
+    @UriParam(label = "advanced")
     private ExecBinding binding;
     @UriParam
     private boolean useStderrOnEmptyStdout;
     @UriParam(defaultValue = "DEBUG")
     private LoggingLevel commandLogLevel = LoggingLevel.DEBUG;
+    @UriParam(label = "advanced")
+    private boolean allowControlHeaders;
 
     public ExecEndpoint(String uri, ExecComponent component) {
         super(uri, component);
-        this.timeout = NO_TIMEOUT;
-        this.binding = new DefaultExecBinding();
     }
 
     @Override
@@ -166,12 +164,10 @@ public class ExecEndpoint extends DefaultEndpoint {
     }
 
     /**
-     * A reference to a org.apache.commons.exec.ExecCommandExecutor in the 
Registry that customizes the command
-     * execution. The default command executor utilizes the commons-exec 
library, which adds a shutdown hook for every
-     * executed command.
+     * To use a custom org.apache.commons.exec.ExecCommandExecutor that 
customizes the command execution. The default
+     * command executor utilizes the commons-exec library, which adds a 
shutdown hook for every executed command.
      */
     public void setCommandExecutor(ExecCommandExecutor commandExecutor) {
-        ObjectHelper.notNull(commandExecutor, "commandExecutor");
         this.commandExecutor = commandExecutor;
     }
 
@@ -180,10 +176,9 @@ public class ExecEndpoint extends DefaultEndpoint {
     }
 
     /**
-     * A reference to a org.apache.commons.exec.ExecBinding in the Registry.
+     * To use a custom org.apache.commons.exec.ExecBinding for advanced 
use-cases.
      */
     public void setBinding(ExecBinding binding) {
-        ObjectHelper.notNull(binding, "binding");
         this.binding = binding;
     }
 
@@ -210,4 +205,17 @@ public class ExecEndpoint extends DefaultEndpoint {
     public void setCommandLogLevel(LoggingLevel commandLogLevel) {
         this.commandLogLevel = commandLogLevel;
     }
+
+    public boolean isAllowControlHeaders() {
+        return allowControlHeaders;
+    }
+
+    /**
+     * Whether to allow to use Camel headers or not (default false). Enabling 
this allows to specify dynamic command
+     * line arguments via message header. However this can be seen as a 
potential security vulnerability if the header
+     * is coming from a malicious user, so use this with care.
+     */
+    public void setAllowControlHeaders(boolean allowControlHeaders) {
+        this.allowControlHeaders = allowControlHeaders;
+    }
 }
diff --git 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
index 6957bf07d44b..b8905e073536 100644
--- 
a/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
+++ 
b/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
@@ -52,16 +52,20 @@ public class DefaultExecBinding implements ExecBinding {
         ObjectHelper.notNull(endpoint, "endpoint");
 
         // do not convert args as we do that manually later
-        Object args = exchange.getIn().removeHeader(EXEC_COMMAND_ARGS);
-        String cmd = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_EXECUTABLE, endpoint.getExecutable(), String.class);
-        String dir = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_WORKING_DIR, endpoint.getWorkingDir(), String.class);
-        long timeout = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_TIMEOUT, endpoint.getTimeout(), Long.class);
+        Object args = endpoint.isAllowControlHeaders() ? 
exchange.getIn().removeHeader(EXEC_COMMAND_ARGS) : null;
+        String cmd = getAndRemoveHeader(endpoint, exchange.getIn(), 
EXEC_COMMAND_EXECUTABLE, endpoint.getExecutable(),
+                String.class);
+        String dir = getAndRemoveHeader(endpoint, exchange.getIn(), 
EXEC_COMMAND_WORKING_DIR, endpoint.getWorkingDir(),
+                String.class);
+        long timeout = getAndRemoveHeader(endpoint, exchange.getIn(), 
EXEC_COMMAND_TIMEOUT, endpoint.getTimeout(), Long.class);
         String exitValuesString
-                = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_EXIT_VALUES, endpoint.getExitValues(), String.class);
-        String outFilePath = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_OUT_FILE, endpoint.getOutFile(), String.class);
-        boolean useStderrOnEmptyStdout = getAndRemoveHeader(exchange.getIn(), 
EXEC_USE_STDERR_ON_EMPTY_STDOUT,
+                = getAndRemoveHeader(endpoint, exchange.getIn(), 
EXEC_COMMAND_EXIT_VALUES, endpoint.getExitValues(),
+                        String.class);
+        String outFilePath
+                = getAndRemoveHeader(endpoint, exchange.getIn(), 
EXEC_COMMAND_OUT_FILE, endpoint.getOutFile(), String.class);
+        boolean useStderrOnEmptyStdout = getAndRemoveHeader(endpoint, 
exchange.getIn(), EXEC_USE_STDERR_ON_EMPTY_STDOUT,
                 endpoint.isUseStderrOnEmptyStdout(), Boolean.class);
-        LoggingLevel commandLogLevel = getAndRemoveHeader(exchange.getIn(), 
EXEC_COMMAND_LOG_LEVEL,
+        LoggingLevel commandLogLevel = getAndRemoveHeader(endpoint, 
exchange.getIn(), EXEC_COMMAND_LOG_LEVEL,
                 endpoint.getCommandLogLevel(), LoggingLevel.class);
         InputStream input = exchange.getIn().getBody(InputStream.class);
 
@@ -83,7 +87,7 @@ public class DefaultExecBinding implements ExecBinding {
         }
 
         Set<Integer> exitValues = new HashSet<>();
-        if (exitValuesString != null && exitValuesString.length() > 0) {
+        if (exitValuesString != null && !exitValuesString.isEmpty()) {
             exitValues = new 
HashSet<>(splitCommaSeparatedToListOfInts(exitValuesString));
         }
 
@@ -140,9 +144,13 @@ public class DefaultExecBinding implements ExecBinding {
      * Gets and removes the <code> <code>headerName</code> header form the 
input <code>message</code> (the header will
      * not be propagated)
      */
-    protected <T> T getAndRemoveHeader(Message message, String headerName, T 
defaultValue, Class<T> headerType) {
-        T h = message.getHeader(headerName, defaultValue, headerType);
-        message.removeHeader(headerName);
+    protected <T> T getAndRemoveHeader(
+            ExecEndpoint endpoint, Message message, String headerName, T 
defaultValue, Class<T> headerType) {
+        T h = defaultValue;
+        if (endpoint.isAllowControlHeaders()) {
+            h = message.getHeader(headerName, defaultValue, headerType);
+            message.removeHeader(headerName);
+        }
         return h;
     }
 }
diff --git 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/DefaultExecBindingTest.java
 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/DefaultExecBindingTest.java
index e408ed447f96..6d85a2d4d446 100644
--- 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/DefaultExecBindingTest.java
+++ 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/DefaultExecBindingTest.java
@@ -20,7 +20,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.camel.Component;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.exec.impl.DefaultExecBinding;
 import org.apache.camel.test.junit6.CamelTestSupport;
@@ -54,7 +53,8 @@ public class DefaultExecBindingTest extends CamelTestSupport {
     }
 
     private ExecEndpoint createExecEndpoint(String uri) throws Exception {
-        Component component = context.getComponent("exec");
+        ExecComponent component = context.getComponent("exec", 
ExecComponent.class);
+        component.setAllowControlHeaders(true);
         return (ExecEndpoint) component.createEndpoint(uri);
     }
 
diff --git 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessRecipientListTest.java
 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessRecipientListTest.java
index f6189b3cd4c6..9e0121c5282b 100644
--- 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessRecipientListTest.java
+++ 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessRecipientListTest.java
@@ -293,6 +293,9 @@ public class ExecJavaProcessRecipientListTest extends 
CamelTestSupport {
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
             public void configure() {
+                // turn on dynamic headers on exec component
+                context.getComponent("exec", 
ExecComponent.class).setAllowControlHeaders(true);
+
                 from("direct:input")
                         .recipientList(header("whereTo")).to("mock:output");
 
diff --git 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
index 0b47a2b2cd18..3c3405b338b9 100644
--- 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
+++ 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
@@ -480,7 +480,7 @@ public class ExecJavaProcessTest extends CamelTestSupport {
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
             public void configure() {
-                from("direct:input").to("exec:java").to("mock:output");
+                
from("direct:input").to("exec:java?allowControlHeaders=true").to("mock:output");
             }
         };
     }
diff --git 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecOutFileTest.java
 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecOutFileTest.java
index a6e424b943a7..0945890f8c55 100644
--- 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecOutFileTest.java
+++ 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecOutFileTest.java
@@ -48,8 +48,8 @@ public class ExecOutFileTest {
 
     private static final File FILE = new File("target/outfiletest.xml");
 
-    @Produce("direct:input")
-    private ProducerTemplate producerTemplate;
+    @Produce("direct:input2")
+    private ProducerTemplate producerTemplate2;
 
     @BeforeEach
     public void setUp() throws IOException {
@@ -106,7 +106,7 @@ public class ExecOutFileTest {
     }
 
     private Exchange sendWithMockedExecutor() {
-        Exchange e = producerTemplate.send(new Processor() {
+        Exchange e = producerTemplate2.send(new Processor() {
             public void process(Exchange exchange) {
                 exchange.getIn().setHeader(EXEC_COMMAND_OUT_FILE, 
FILE.getPath());
                 exchange.getIn().setBody(FILE_CONTENT);
diff --git 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecProducerTest.java
 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecProducerTest.java
index 5b454b5ab056..fb77c129d2d4 100644
--- 
a/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecProducerTest.java
+++ 
b/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecProducerTest.java
@@ -53,6 +53,8 @@ public class ExecProducerTest {
 
     @Produce("direct:input")
     private ProducerTemplate producerTemplate;
+    @Produce("direct:input2")
+    private ProducerTemplate producerTemplate2;
 
     @Autowired
     private ExecCommandExecutorMock execCommandExecutorMock;
@@ -70,7 +72,7 @@ public class ExecProducerTest {
     public void testOverrideExecutable() {
         final String command = "java";
 
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
 
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("noinput");
@@ -88,7 +90,7 @@ public class ExecProducerTest {
     @DirtiesContext
     public void testOverrideArgs() {
         final String[] args = { "-version", "classpath:c:/program files/test/" 
};
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
 
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("noinput");
@@ -104,7 +106,7 @@ public class ExecProducerTest {
     @Test
     @DirtiesContext
     public void testOverrideTimeout() {
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
 
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("noinput");
@@ -117,7 +119,7 @@ public class ExecProducerTest {
     @Test
     @DirtiesContext
     public void testExitValues() {
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
 
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("noinput");
@@ -130,7 +132,7 @@ public class ExecProducerTest {
     @Test
     @DirtiesContext
     public void testExitValueNone() {
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
 
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("noinput");
@@ -191,7 +193,7 @@ public class ExecProducerTest {
     public void testOverrideWorkingDir() {
         final String workingDir = "c:/program files/test";
 
-        producerTemplate.send(new Processor() {
+        producerTemplate2.send(new Processor() {
             public void process(Exchange exchange) {
                 exchange.getIn().setBody("");
                 exchange.getIn().setHeader(EXEC_COMMAND_WORKING_DIR, 
workingDir);
diff --git 
a/components/camel-exec/src/test/resources/org/apache/camel/component/exec/exec-mock-executor-context.xml
 
b/components/camel-exec/src/test/resources/org/apache/camel/component/exec/exec-mock-executor-context.xml
index 1cc52ad82173..820297aa06e5 100644
--- 
a/components/camel-exec/src/test/resources/org/apache/camel/component/exec/exec-mock-executor-context.xml
+++ 
b/components/camel-exec/src/test/resources/org/apache/camel/component/exec/exec-mock-executor-context.xml
@@ -31,6 +31,11 @@
       <to
         
uri="exec:mockedByCommandExecutorMock.exe?commandExecutor=#commandExecutorMock"/>
     </route>
+    <route>
+      <from uri="direct:input2"/>
+      <to
+        
uri="exec:mockedByCommandExecutorMock.exe?commandExecutor=#commandExecutorMock&amp;allowControlHeaders=true"/>
+    </route>
   </camelContext>
 
   <bean id="commandExecutorMock"
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_20.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_20.adoc
index f2c4391e8c88..e81069682919 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_20.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_20.adoc
@@ -13,6 +13,13 @@ See the xref:camel-upgrade-recipes-tool.adoc[documentation] 
page for details.
 
 == Upgrading Camel 4.19 to 4.20
 
+=== camel-exec
+
+The `camel-exec` component is made more restrict by default, as the command 
line arguments, and other parameters
+cannot be dynamic provided from Camel message headers. To allow this you now 
have to enable this by setting
+`allowControlHeaders=true` on either the component (globally) or per endpoint 
when needed.
+
+
 === camel-pulsar
 
 The Apache Pulsar client library has been upgraded from 4.1.3 to 4.2.0.
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ExecComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ExecComponentBuilderFactory.java
index f024a853157e..5768d84bf5c4 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ExecComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ExecComponentBuilderFactory.java
@@ -75,6 +75,60 @@ public interface ExecComponentBuilderFactory {
             return this;
         }
     
+        /**
+         * The timeout, in milliseconds, after which the executable should be
+         * terminated. If execution has not completed within the timeout, the
+         * component will send a termination request.
+         * 
+         * The option is a: &lt;code&gt;long&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param timeout the value to set
+         * @return the dsl builder
+         */
+        default ExecComponentBuilder timeout(long timeout) {
+            doSetProperty("timeout", timeout);
+            return this;
+        }
+    
+        /**
+         * The directory in which the command should be executed. If null, the
+         * working directory of the current process will be used.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: producer
+         * 
+         * @param workingDir the value to set
+         * @return the dsl builder
+         */
+        default ExecComponentBuilder workingDir(java.lang.String workingDir) {
+            doSetProperty("workingDir", workingDir);
+            return this;
+        }
+    
+        
+        /**
+         * Whether to allow to use Camel headers or not (default false).
+         * Enabling this allows to specify dynamic command line arguments via
+         * message header. However this can be seen as a potential security
+         * vulnerability if the header is coming from a malicious user, so use
+         * this with care.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param allowControlHeaders the value to set
+         * @return the dsl builder
+         */
+        default ExecComponentBuilder allowControlHeaders(boolean 
allowControlHeaders) {
+            doSetProperty("allowControlHeaders", allowControlHeaders);
+            return this;
+        }
+    
         
         /**
          * Whether autowiring is enabled. This is used for automatic autowiring
@@ -96,6 +150,43 @@ public interface ExecComponentBuilderFactory {
             doSetProperty("autowiredEnabled", autowiredEnabled);
             return this;
         }
+    
+        /**
+         * To use a custom org.apache.commons.exec.ExecBinding for advanced
+         * use-cases.
+         * 
+         * The option is a:
+         * &lt;code&gt;org.apache.camel.component.exec.ExecBinding&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param binding the value to set
+         * @return the dsl builder
+         */
+        default ExecComponentBuilder 
binding(org.apache.camel.component.exec.ExecBinding binding) {
+            doSetProperty("binding", binding);
+            return this;
+        }
+    
+        /**
+         * To use a custom org.apache.commons.exec.ExecCommandExecutor that
+         * customizes the command execution. The default command executor
+         * utilizes the commons-exec library, which adds a shutdown hook for
+         * every executed command.
+         * 
+         * The option is a:
+         * 
&lt;code&gt;org.apache.camel.component.exec.ExecCommandExecutor&lt;/code&gt; 
type.
+         * 
+         * Group: advanced
+         * 
+         * @param commandExecutor the value to set
+         * @return the dsl builder
+         */
+        default ExecComponentBuilder 
commandExecutor(org.apache.camel.component.exec.ExecCommandExecutor 
commandExecutor) {
+            doSetProperty("commandExecutor", commandExecutor);
+            return this;
+        }
     }
 
     class ExecComponentBuilderImpl
@@ -112,7 +203,12 @@ public interface ExecComponentBuilderFactory {
                 Object value) {
             switch (name) {
             case "lazyStartProducer": ((ExecComponent) 
component).setLazyStartProducer((boolean) value); return true;
+            case "timeout": ((ExecComponent) component).setTimeout((long) 
value); return true;
+            case "workingDir": ((ExecComponent) 
component).setWorkingDir((java.lang.String) value); return true;
+            case "allowControlHeaders": ((ExecComponent) 
component).setAllowControlHeaders((boolean) value); return true;
             case "autowiredEnabled": ((ExecComponent) 
component).setAutowiredEnabled((boolean) value); return true;
+            case "binding": ((ExecComponent) 
component).setBinding((org.apache.camel.component.exec.ExecBinding) value); 
return true;
+            case "commandExecutor": ((ExecComponent) 
component).setCommandExecutor((org.apache.camel.component.exec.ExecCommandExecutor)
 value); return true;
             default: return false;
             }
         }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ExecEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ExecEndpointBuilderFactory.java
index caff8ec882b6..92b503e52e0b 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ExecEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ExecEndpointBuilderFactory.java
@@ -58,74 +58,6 @@ public interface ExecEndpointBuilderFactory {
             doSetProperty("args", args);
             return this;
         }
-        /**
-         * A reference to a org.apache.commons.exec.ExecBinding in the 
Registry.
-         * 
-         * The option is a:
-         * <code>org.apache.camel.component.exec.ExecBinding</code> type.
-         * 
-         * Group: producer
-         * 
-         * @param binding the value to set
-         * @return the dsl builder
-         */
-        default ExecEndpointBuilder 
binding(org.apache.camel.component.exec.ExecBinding binding) {
-            doSetProperty("binding", binding);
-            return this;
-        }
-        /**
-         * A reference to a org.apache.commons.exec.ExecBinding in the 
Registry.
-         * 
-         * The option will be converted to a
-         * <code>org.apache.camel.component.exec.ExecBinding</code> type.
-         * 
-         * Group: producer
-         * 
-         * @param binding the value to set
-         * @return the dsl builder
-         */
-        default ExecEndpointBuilder binding(String binding) {
-            doSetProperty("binding", binding);
-            return this;
-        }
-        /**
-         * A reference to a org.apache.commons.exec.ExecCommandExecutor in the
-         * Registry that customizes the command execution. The default command
-         * executor utilizes the commons-exec library, which adds a shutdown
-         * hook for every executed command.
-         * 
-         * The option is a:
-         * <code>org.apache.camel.component.exec.ExecCommandExecutor</code>
-         * type.
-         * 
-         * Group: producer
-         * 
-         * @param commandExecutor the value to set
-         * @return the dsl builder
-         */
-        default ExecEndpointBuilder 
commandExecutor(org.apache.camel.component.exec.ExecCommandExecutor 
commandExecutor) {
-            doSetProperty("commandExecutor", commandExecutor);
-            return this;
-        }
-        /**
-         * A reference to a org.apache.commons.exec.ExecCommandExecutor in the
-         * Registry that customizes the command execution. The default command
-         * executor utilizes the commons-exec library, which adds a shutdown
-         * hook for every executed command.
-         * 
-         * The option will be converted to a
-         * <code>org.apache.camel.component.exec.ExecCommandExecutor</code>
-         * type.
-         * 
-         * Group: producer
-         * 
-         * @param commandExecutor the value to set
-         * @return the dsl builder
-         */
-        default ExecEndpointBuilder commandExecutor(String commandExecutor) {
-            doSetProperty("commandExecutor", commandExecutor);
-            return this;
-        }
         /**
          * Logging level to be used for commands during execution. The default
          * value is DEBUG. Possible values are TRACE, DEBUG, INFO, WARN, ERROR
@@ -333,6 +265,114 @@ public interface ExecEndpointBuilderFactory {
             doSetProperty("lazyStartProducer", lazyStartProducer);
             return this;
         }
+        /**
+         * Whether to allow to use Camel headers or not (default false).
+         * Enabling this allows to specify dynamic command line arguments via
+         * message header. However this can be seen as a potential security
+         * vulnerability if the header is coming from a malicious user, so use
+         * this with care.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param allowControlHeaders the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder allowControlHeaders(boolean 
allowControlHeaders) {
+            doSetProperty("allowControlHeaders", allowControlHeaders);
+            return this;
+        }
+        /**
+         * Whether to allow to use Camel headers or not (default false).
+         * Enabling this allows to specify dynamic command line arguments via
+         * message header. However this can be seen as a potential security
+         * vulnerability if the header is coming from a malicious user, so use
+         * this with care.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param allowControlHeaders the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder allowControlHeaders(String 
allowControlHeaders) {
+            doSetProperty("allowControlHeaders", allowControlHeaders);
+            return this;
+        }
+        /**
+         * To use a custom org.apache.commons.exec.ExecBinding for advanced
+         * use-cases.
+         * 
+         * The option is a:
+         * <code>org.apache.camel.component.exec.ExecBinding</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param binding the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder 
binding(org.apache.camel.component.exec.ExecBinding binding) {
+            doSetProperty("binding", binding);
+            return this;
+        }
+        /**
+         * To use a custom org.apache.commons.exec.ExecBinding for advanced
+         * use-cases.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.component.exec.ExecBinding</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param binding the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder binding(String binding) {
+            doSetProperty("binding", binding);
+            return this;
+        }
+        /**
+         * To use a custom org.apache.commons.exec.ExecCommandExecutor that
+         * customizes the command execution. The default command executor
+         * utilizes the commons-exec library, which adds a shutdown hook for
+         * every executed command.
+         * 
+         * The option is a:
+         * <code>org.apache.camel.component.exec.ExecCommandExecutor</code>
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param commandExecutor the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder 
commandExecutor(org.apache.camel.component.exec.ExecCommandExecutor 
commandExecutor) {
+            doSetProperty("commandExecutor", commandExecutor);
+            return this;
+        }
+        /**
+         * To use a custom org.apache.commons.exec.ExecCommandExecutor that
+         * customizes the command execution. The default command executor
+         * utilizes the commons-exec library, which adds a shutdown hook for
+         * every executed command.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.component.exec.ExecCommandExecutor</code>
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param commandExecutor the value to set
+         * @return the dsl builder
+         */
+        default AdvancedExecEndpointBuilder commandExecutor(String 
commandExecutor) {
+            doSetProperty("commandExecutor", commandExecutor);
+            return this;
+        }
     }
 
     public interface ExecBuilders {

Reply via email to