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

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


The following commit(s) were added to refs/heads/main by this push:
     new 5ab43431e22b CAMEL-24295: anchor the security-scan option match on a 
token boundary, and mark the Simple nested option (#27117)
5ab43431e22b is described below

commit 5ab43431e22bb68e329c2180913f217fcbe56b2e
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Oct 2 16:19:26 2026 +0200

    CAMEL-24295: anchor the security-scan option match on a token boundary, and 
mark the Simple nested option (#27117)
    
    Co-authored-by: Claude Opus 4.8 <[email protected]>
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../org/apache/camel/catalog/languages/file.json   |  2 +-
 .../org/apache/camel/catalog/languages/simple.json |  2 +-
 .../org/apache/camel/catalog/models/simple.json    |  2 +-
 .../camel/catalog/schemas/camelYamlDsl-model.json  |  4 +-
 .../org/apache/camel/language/simple/file.json     |  2 +-
 .../org/apache/camel/language/simple/simple.json   |  2 +-
 .../org/apache/camel/model/language/simple.json    |  2 +-
 .../camel/model/language/SimpleExpression.java     |  3 +-
 .../java/org/apache/camel/util/SecurityUtils.java  | 27 ++++++++++-
 .../org/apache/camel/util/SecurityUtilsTest.java   | 33 ++++++++++++++
 .../jbang/core/commands/mcp/SecurityScanTools.java |  6 +++
 .../core/commands/mcp/SecurityScanToolsTest.java   | 53 ++++++++++++++++++++++
 .../resources/schema/camelYamlDsl-model.json       |  4 +-
 13 files changed, 130 insertions(+), 12 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
index 90523bcc10d2..f247bf77992d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json
@@ -20,7 +20,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
index d3c1a3ef82db..d7286003a364 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
@@ -20,7 +20,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json
index 16ae4e0aa725..54a83ef0c577 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json
@@ -17,7 +17,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
index 6c97b9d7b50c..3b2a2b3e4daf 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camelYamlDsl-model.json
@@ -16118,8 +16118,8 @@
         "displayName" : "Nested",
         "kind" : "attribute",
         "index" : 4,
-        "group" : "advanced",
-        "label" : "advanced"
+        "group" : "security",
+        "label" : "advanced,security"
       }, {
         "name" : "resultType",
         "type" : "string",
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
index 90523bcc10d2..f247bf77992d 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json
@@ -20,7 +20,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
index d3c1a3ef82db..d7286003a364 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
@@ -20,7 +20,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json
index 16ae4e0aa725..54a83ef0c577 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json
@@ -17,7 +17,7 @@
     "expression": { "index": 1, "kind": "value", "displayName": "Expression", 
"group": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The expression value in your chosen language syntax." },
     "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim 
Result", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to trim the returned values when 
this language is in use." },
     "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", 
"group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To pretty format the output (only JSon 
or XML supported)." },
-    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If the result is a 
nested simple expression should this expression be evaluated as well." },
+    "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", 
"group": "security", "label": "advanced,security", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "security": "insecure:dev", "defaultValue": false, 
"description": "If the result is a nested simple expression should this 
expression be evaluated as well." },
     "resultType": { "index": 5, "kind": "attribute", "displayName": "Result 
Type", "group": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The class of the result type (type from output)." },
     "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": 
"advanced", "label": "advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
source code to remove leading and trailing whitespaces and line breaks." },
     "resolveResource": { "index": 7, "kind": "attribute", "displayName": 
"Resolve Resource", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether a result of the expression that is a String starting with resource: is 
loaded as a resource and its content becomes the result, e.g. a script that 
returns resource:file:order.json o [...]
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java
index 185efe73ba12..aa457250cde0 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java
@@ -43,7 +43,8 @@ public class SimpleExpression extends 
TypedExpressionDefinition {
               description = "To pretty format the output (only JSon or XML 
supported).")
     private String pretty;
     @XmlAttribute
-    @Metadata(defaultValue = "false", javaType = "java.lang.Boolean", label = 
"advanced",
+    @Metadata(defaultValue = "false", javaType = "java.lang.Boolean", label = 
"advanced,security",
+              security = "insecure:dev",
               description = "If the result is a nested simple expression 
should this expression be evaluated as well.")
     private String nested;
 
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java 
b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
index 654991dac107..b0a785925b59 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SecurityUtils.java
@@ -80,6 +80,7 @@ public final class SecurityUtils {
         map.put("ignoresslverification", new SecurityOption(INSECURE_SSL, 
"true"));
         map.put("ignoresslwarnings", new SecurityOption(INSECURE_SSL, "true"));
         map.put("knownhostsresource", new SecurityOption(INSECURE_SSL, ""));
+        map.put("nested", new SecurityOption(INSECURE_DEV, "true"));
         map.put("objectcodecpattern", new 
SecurityOption(INSECURE_SERIALIZATION, ""));
         map.put("objectmessageenabled", new 
SecurityOption(INSECURE_SERIALIZATION, "true"));
         map.put("sendenabled", new SecurityOption(INSECURE_DEV, "true"));
@@ -170,6 +171,9 @@ public final class SecurityUtils {
                 "component:oaipmh"));
         owners.put("knownhostsresource", Set.of(
                 "component:ssh"));
+        owners.put("nested", Set.of(
+                "language:file",
+                "language:simple"));
         owners.put("objectcodecpattern", Set.of(
                 "component:mina"));
         owners.put("objectmessageenabled", Set.of(
@@ -293,7 +297,9 @@ public final class SecurityUtils {
      * <p>
      * A key that identifies a component, data format or language (such as 
{@code camel.component.netty.ssl}) only
      * matches a security option that this component, data format or language 
declares. Any other key (such as a
-     * camel-main option, or an option name without a prefix) matches by the 
option name.
+     * camel-main option, or an option name without a prefix) matches by the 
option name, except that a configuration
+     * key never matches an option that only languages declare (such as {@code 
camel.beans.foo.nested} for the
+     * {@code nested} option of the simple language).
      *
      * @param  text the configuration property key (e.g., 
"camel.component.aws2-s3.trustAllCertificates")
      * @return      the security option info, or null if the property has no 
security category
@@ -308,10 +314,29 @@ public final class SecurityUtils {
                 // the option has the same name as a security option of 
another component, data format or language
                 return null;
             }
+            if (owner == null && owners != null && text.indexOf('.') >= 0 && 
isDeclaredByLanguagesOnly(owners)) {
+                // a language option is set on an expression in a route, which 
is checked by its bare option name, or
+                // under camel.language.<name>. - any other configuration key 
(camel.beans.*, camel.main.*, ...) that
+                // merely ends with the same name is not this option. 
Component and data format options keep matching
+                // such keys by name, as camel.beans.* can configure a 
component or data format bean.
+                return null;
+            }
         }
         return answer;
     }
 
+    private static boolean isDeclaredByLanguagesOnly(Set<String> owners) {
+        if (owners.isEmpty()) {
+            return false;
+        }
+        for (String owner : owners) {
+            if (!owner.startsWith("language:")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * The owner of a configuration property key that identifies a component, 
data format or language, such as
      * {@code component:nettyhttp} for {@code camel.component.netty-http.ssl}, 
or null for any other key.
diff --git 
a/core/camel-util/src/test/java/org/apache/camel/util/SecurityUtilsTest.java 
b/core/camel-util/src/test/java/org/apache/camel/util/SecurityUtilsTest.java
index 29e3606f25c3..ce1f1816ccd9 100644
--- a/core/camel-util/src/test/java/org/apache/camel/util/SecurityUtilsTest.java
+++ b/core/camel-util/src/test/java/org/apache/camel/util/SecurityUtilsTest.java
@@ -268,6 +268,39 @@ class SecurityUtilsTest {
         
assertNotNull(SecurityUtils.getSecurityOption("camel.main.devConsoleEnabled"));
     }
 
+    @Test
+    void testLanguageOptionMatchesOnlyItsOwnLanguage() {
+        // nested is declared only by the simple and file languages
+        
assertTrue(SecurityUtils.isInsecureValue("camel.language.simple.nested", 
"true"));
+        assertTrue(SecurityUtils.isInsecureValue("camel.language.file.nested", 
"true"));
+        
assertNull(SecurityUtils.getSecurityOption("camel.language.xpath.nested"));
+        // the bare option name, as the security scanner checks an expression 
in a route, still matches
+        assertTrue(SecurityUtils.isInsecureValue("nested", "true"));
+        // any other configuration key that merely ends with the same name is 
not the language option
+        assertNull(SecurityUtils.getSecurityOption("camel.beans.foo.nested"));
+        assertNull(SecurityUtils.getSecurityOption("camel.main.nested"));
+        
assertNull(SecurityUtils.getSecurityOption("camel.kamelet.myKamelet.nested"));
+        // component options keep matching such keys by name, as camel.beans.* 
can configure a component bean
+        
assertNotNull(SecurityUtils.getSecurityOption("camel.beans.myClient.trustAllCertificates"));
+    }
+
+    @Test
+    void testDetectViolationsIgnoresBeanPropertyNamedLikeALanguageOption() {
+        Map<String, Object> properties = new LinkedHashMap<>();
+        properties.put("camel.beans.foo.nested", "true");
+        properties.put("camel.language.simple.nested", "true");
+
+        List<SecurityViolation> violations = SecurityUtils.detectViolations(
+                properties,
+                (k, v) -> false,
+                category -> "fail",
+                Set.of());
+
+        assertEquals(1, violations.size());
+        assertEquals("camel.language.simple.nested", 
violations.get(0).propertyKey());
+        assertEquals(SecurityUtils.INSECURE_DEV, violations.get(0).category());
+    }
+
     @Test
     void testDetectViolationsOnlyForTheOwningComponent() {
         Map<String, Object> properties = new LinkedHashMap<>();
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanTools.java
index 55a56b6cb54f..ca872b096ca0 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanTools.java
@@ -146,6 +146,12 @@ public class SecurityScanTools {
             if (idx < 0) {
                 return null;
             }
+            // require a token boundary before the key, so a longer identifier 
that merely ends in the key
+            // (isNested, unnested, an unrelated ...nested field) is not 
treated as this option
+            if (idx > 0 && Character.isLetterOrDigit(normalized.charAt(idx - 
1))) {
+                from = idx + 1;
+                continue;
+            }
             int after = idx + optionKey.length();
             // a quoted key ("key":value) leaves a closing quote before the 
separator
             if (after < normalized.length() && normalized.charAt(after) == 
'"') {
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanToolsTest.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanToolsTest.java
index 0e7ca9da2beb..45e74ef7bb80 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanToolsTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/SecurityScanToolsTest.java
@@ -69,6 +69,59 @@ class SecurityScanToolsTest {
                 && f.category().equals("insecure:ssl"));
     }
 
+    @Test
+    void securityOptionMatchingIsAnchoredOnTokenBoundaries() {
+        // startTls ends in the "tls" security option but is a different 
option; without a token-boundary check it was
+        // reported as an insecure tls=false
+        SecurityScanTools.SecurityScanResult falsePositive = 
tools.camel_security_scan("""
+                - route:
+                    from:
+                      uri: smtp://mail.example.com?startTls=false
+                """, "yaml");
+        assertThat(falsePositive.findings()).noneMatch(f -> 
f.issue().contains("tls="));
+
+        // a boundary-delimited tls=false is still detected
+        SecurityScanTools.SecurityScanResult real = 
tools.camel_security_scan("""
+                - route:
+                    from:
+                      uri: netty://host:9999?tls=false
+                """, "yaml");
+        assertThat(real.findings())
+                .anyMatch(f -> f.issue().contains("tls=false") && 
f.category().equals("insecure:ssl"));
+    }
+
+    @Test
+    void detectsNestedSimpleExpression() {
+        // nested=true evaluates the result of the expression as another 
simple expression
+        SecurityScanTools.SecurityScanResult nested = 
tools.camel_security_scan("""
+                - route:
+                    from:
+                      uri: direct:start
+                      steps:
+                        - setBody:
+                            simple:
+                              expression: "${header.template}"
+                              nested: true
+                """, "yaml");
+        assertThat(nested.findings())
+                .anyMatch(f -> f.issue().contains("nested=true") && 
f.category().equals("insecure:dev"));
+
+        SecurityScanTools.SecurityScanResult notNested = 
tools.camel_security_scan("""
+                - route:
+                    from:
+                      uri: direct:start
+                      steps:
+                        - setBody:
+                            simple:
+                              expression: "${header.template}"
+                              nested: false
+                        - setHeader:
+                            name: isNested
+                            constant: "unnested: true"
+                """, "yaml");
+        assertThat(notNested.findings()).noneMatch(f -> 
f.issue().contains("nested="));
+    }
+
     @Test
     void detectsAllowJavaSerializedObject() {
         String route = """
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
index 6c97b9d7b50c..3b2a2b3e4daf 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-model.json
@@ -16118,8 +16118,8 @@
         "displayName" : "Nested",
         "kind" : "attribute",
         "index" : 4,
-        "group" : "advanced",
-        "label" : "advanced"
+        "group" : "security",
+        "label" : "advanced,security"
       }, {
         "name" : "resultType",
         "type" : "string",

Reply via email to