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 4a6d8e876920 CAMEL-25096: camel-core - Properties component: mask the 
values of vault functions and sensitive keys when logging (#26997)
4a6d8e876920 is described below

commit 4a6d8e8769204895b3b6e87de0f5021d41f80656
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Sep 29 07:35:26 2026 +0200

    CAMEL-25096: camel-core - Properties component: mask the values of vault 
functions and sensitive keys when logging (#26997)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../apache/camel/catalog/main/sensitive-keys.json  |   2 +
 .../ParameterStorePropertiesFunction.java          |   6 +
 .../SecretsManagerPropertiesFunction.java          |   6 +
 .../key/vault/KeyVaultPropertiesFunction.java      |   6 +
 .../vault/CyberArkVaultPropertiesFunction.java     |   6 +
 .../GoogleSecretManagerPropertiesFunction.java     |   6 +
 .../vault/HashicorpVaultPropertiesFunction.java    |   6 +
 .../IBMSecretsManagerPropertiesFunction.java       |   6 +
 .../properties/BaseSecretPropertiesFunction.java   |   6 +
 .../org/apache/camel/spi/PropertiesFunction.java   |  11 ++
 .../properties/DefaultPropertiesLookup.java        |  15 ++-
 .../properties/DefaultPropertiesParser.java        |  26 ++--
 .../component/properties/PropertiesComponent.java  |  52 +++++++-
 .../camel/impl/console/PropertiesDevConsole.java   |   7 +-
 .../PropertiesComponentMaskSensitiveLogTest.java   | 140 +++++++++++++++++++++
 .../java/org/apache/camel/util/SensitiveUtils.java |   4 +
 .../org/apache/camel/util/SensitiveUtilsTest.java  |   2 +
 .../maven/packaging/UpdateSensitizeHelper.java     |   3 +-
 18 files changed, 296 insertions(+), 14 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
index f34b628431b6..c42327768a19 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/sensitive-keys.json
@@ -10,6 +10,7 @@
   "api_secret",
   "apikey",
   "apipassword",
+  "apisecret",
   "apiuser",
   "apiusername",
   "authenticationtoken",
@@ -34,6 +35,7 @@
   "databasesslkeystorepassword",
   "databasesslpassword",
   "databasessltruststorepassword",
+  "db_password",
   "emailaddress",
   "functionkey",
   "hostkey",
diff --git 
a/components/camel-aws/camel-aws-parameter-store/src/main/java/org/apache/camel/component/aws/parameterstore/ParameterStorePropertiesFunction.java
 
b/components/camel-aws/camel-aws-parameter-store/src/main/java/org/apache/camel/component/aws/parameterstore/ParameterStorePropertiesFunction.java
index 646980fdce4a..799ef380c079 100644
--- 
a/components/camel-aws/camel-aws-parameter-store/src/main/java/org/apache/camel/component/aws/parameterstore/ParameterStorePropertiesFunction.java
+++ 
b/components/camel-aws/camel-aws-parameter-store/src/main/java/org/apache/camel/component/aws/parameterstore/ParameterStorePropertiesFunction.java
@@ -207,6 +207,12 @@ public class ParameterStorePropertiesFunction extends 
ServiceSupport implements
         return "aws-parameterstore";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
 
b/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
index e606a2a25ccc..8813a510e721 100644
--- 
a/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
+++ 
b/components/camel-aws/camel-aws-secrets-manager/src/main/java/org/apache/camel/component/aws/secretsmanager/SecretsManagerPropertiesFunction.java
@@ -211,6 +211,12 @@ public class SecretsManagerPropertiesFunction extends 
ServiceSupport implements
         return "aws";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-azure/camel-azure-key-vault/src/main/java/org/apache/camel/component/azure/key/vault/KeyVaultPropertiesFunction.java
 
b/components/camel-azure/camel-azure-key-vault/src/main/java/org/apache/camel/component/azure/key/vault/KeyVaultPropertiesFunction.java
index c6903b40ee22..97b04ef74835 100644
--- 
a/components/camel-azure/camel-azure-key-vault/src/main/java/org/apache/camel/component/azure/key/vault/KeyVaultPropertiesFunction.java
+++ 
b/components/camel-azure/camel-azure-key-vault/src/main/java/org/apache/camel/component/azure/key/vault/KeyVaultPropertiesFunction.java
@@ -160,6 +160,12 @@ public class KeyVaultPropertiesFunction extends 
ServiceSupport implements Proper
         return "azure";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-cyberark-vault/src/main/java/org/apache/camel/component/cyberark/vault/CyberArkVaultPropertiesFunction.java
 
b/components/camel-cyberark-vault/src/main/java/org/apache/camel/component/cyberark/vault/CyberArkVaultPropertiesFunction.java
index d1bc3a40453b..365bb2d5ba69 100644
--- 
a/components/camel-cyberark-vault/src/main/java/org/apache/camel/component/cyberark/vault/CyberArkVaultPropertiesFunction.java
+++ 
b/components/camel-cyberark-vault/src/main/java/org/apache/camel/component/cyberark/vault/CyberArkVaultPropertiesFunction.java
@@ -162,6 +162,12 @@ public class CyberArkVaultPropertiesFunction extends 
ServiceSupport implements P
         return "cyberark";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-google/camel-google-secret-manager/src/main/java/org/apache/camel/component/google/secret/manager/GoogleSecretManagerPropertiesFunction.java
 
b/components/camel-google/camel-google-secret-manager/src/main/java/org/apache/camel/component/google/secret/manager/GoogleSecretManagerPropertiesFunction.java
index dc2539badc3b..7acba28405ed 100644
--- 
a/components/camel-google/camel-google-secret-manager/src/main/java/org/apache/camel/component/google/secret/manager/GoogleSecretManagerPropertiesFunction.java
+++ 
b/components/camel-google/camel-google-secret-manager/src/main/java/org/apache/camel/component/google/secret/manager/GoogleSecretManagerPropertiesFunction.java
@@ -143,6 +143,12 @@ public class GoogleSecretManagerPropertiesFunction extends 
ServiceSupport implem
         return "gcp";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultPropertiesFunction.java
 
b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultPropertiesFunction.java
index 60b40d0a1f3a..bb195d3ac1cf 100644
--- 
a/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultPropertiesFunction.java
+++ 
b/components/camel-hashicorp-vault/src/main/java/org/apache/camel/component/hashicorp/vault/HashicorpVaultPropertiesFunction.java
@@ -145,6 +145,12 @@ public class HashicorpVaultPropertiesFunction extends 
ServiceSupport implements
         return "hashicorp";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-ibm/camel-ibm-secrets-manager/src/main/java/org/apache/camel/component/ibm/secrets/manager/IBMSecretsManagerPropertiesFunction.java
 
b/components/camel-ibm/camel-ibm-secrets-manager/src/main/java/org/apache/camel/component/ibm/secrets/manager/IBMSecretsManagerPropertiesFunction.java
index b63deca23517..bf57267763fa 100644
--- 
a/components/camel-ibm/camel-ibm-secrets-manager/src/main/java/org/apache/camel/component/ibm/secrets/manager/IBMSecretsManagerPropertiesFunction.java
+++ 
b/components/camel-ibm/camel-ibm-secrets-manager/src/main/java/org/apache/camel/component/ibm/secrets/manager/IBMSecretsManagerPropertiesFunction.java
@@ -127,6 +127,12 @@ public class IBMSecretsManagerPropertiesFunction extends 
ServiceSupport implemen
         return "ibm";
     }
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     public String apply(String remainder) {
         String key = remainder;
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseSecretPropertiesFunction.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseSecretPropertiesFunction.java
index 452458960dba..1f2fad46e535 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseSecretPropertiesFunction.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/properties/BaseSecretPropertiesFunction.java
@@ -28,6 +28,12 @@ import org.apache.camel.spi.PropertiesFunction;
  */
 abstract class BaseSecretPropertiesFunction extends BasePropertiesFunction {
 
+    @Override
+    public boolean isSensitive() {
+        // the values are secrets
+        return true;
+    }
+
     @Override
     Path getMountPath() {
         if (getMountPathSecrets() != null) {
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunction.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunction.java
index 331f1c9b281c..bc0484ae324b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunction.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesFunction.java
@@ -70,4 +70,15 @@ public interface PropertiesFunction {
         return false;
     }
 
+    /**
+     * Whether the values returned by this function are sensitive (such as 
secrets from a vault), which should not be
+     * logged.
+     *
+     * @return true if the values are sensitive
+     * @since  4.23
+     */
+    default boolean isSensitive() {
+        return false;
+    }
+
 }
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesLookup.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesLookup.java
index 61578449bb00..5ca67644b06a 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesLookup.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesLookup.java
@@ -24,6 +24,7 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.LoadablePropertiesSource;
 import org.apache.camel.spi.PropertiesSource;
 import org.apache.camel.util.OrderedLocationProperties;
+import org.apache.camel.util.SensitiveUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,7 +46,9 @@ public class DefaultPropertiesLookup implements 
PropertiesLookup {
     public String lookup(String name, String defaultValue) {
         try {
             String answer = doLookup(name, defaultValue);
-            LOG.trace("lookup(name: {} default: {}) -> {}", name, 
defaultValue, answer);
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("lookup(name: {} default: {}) -> {}", name, 
mask(name, defaultValue), mask(name, answer));
+            }
             return answer;
         } catch (NoTypeConversionAvailableException e) {
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
@@ -126,7 +129,10 @@ public class DefaultPropertiesLookup implements 
PropertiesLookup {
     }
 
     private void onLookup(String name, String value, String defaultValue, 
String source) {
-        LOG.trace("Property (name: {} default: {}) resolved from source: {} -> 
{}", name, defaultValue, source, value);
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Property (name: {} default: {}) resolved from source: 
{} -> {}", name, mask(name, defaultValue), source,
+                    mask(name, value));
+        }
         for (PropertiesLookupListener listener : 
component.getPropertiesLookupListeners()) {
             try {
                 listener.onLookup(name, value, defaultValue, source);
@@ -147,4 +153,9 @@ public class DefaultPropertiesLookup implements 
PropertiesLookup {
         }
         return loc;
     }
+
+    private static String mask(String name, String value) {
+        // do not log sensitive values (such as passwords)
+        return value != null && name != null && 
SensitiveUtils.containsSensitive(name) ? "xxxxxx" : value;
+    }
 }
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java
index 932936182470..3bb4eb201663 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java
@@ -24,6 +24,7 @@ import org.apache.camel.PropertiesLookupListener;
 import org.apache.camel.spi.PropertiesFunction;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.OrderedLocationProperties;
+import org.apache.camel.util.SensitiveUtils;
 import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,6 +39,9 @@ import static 
org.apache.camel.util.IOHelper.lookupEnvironmentVariable;
  */
 public class DefaultPropertiesParser implements PropertiesParser {
 
+    // the mask of sensitive values (such as passwords) when logged
+    private static final String MASK = "xxxxxx";
+
     private static final String UNRESOLVED_PREFIX_TOKEN = "@@[";
 
     private static final String UNRESOLVED_SUFFIX_TOKEN = "]@@";
@@ -401,7 +405,7 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
                     } else {
                         if (log.isDebugEnabled()) {
                             log.debug("Property with key [{}] applied by 
function [{}] -> {}", key, function.getName(),
-                                    value);
+                                    function.isSensitive() ? MASK : 
mask(StringHelper.after(key, ":"), value));
                         }
                         String k = prevKey != null ? prevKey : key;
                         propertiesComponent.updateResolvedValue(k, value, 
function.getName());
@@ -419,7 +423,7 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
 
             String value = doGetPropertyValue(key, defaultValue);
             if (value == null && defaultValue != null) {
-                log.debug("Property with key [{}] not found, using default 
value: {}", key, defaultValue);
+                log.debug("Property with key [{}] not found, using default 
value: {}", key, mask(key, defaultValue));
                 value = defaultValue;
                 for (PropertiesLookupListener listener : 
propertiesComponent.getPropertiesLookupListeners()) {
                     try {
@@ -481,7 +485,7 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
                         }
                     }
                     onLookup(key, value, localDefaultValue, loc);
-                    log.debug("Found local property: {} with value: {} to be 
used.", key, value);
+                    log.debug("Found local property: {} with value: {} to be 
used.", key, mask(key, value));
                 }
             }
 
@@ -497,21 +501,21 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
                 value = lookupEnvironmentVariable(key);
                 if (value != null) {
                     onLookup(key, value, defaultValue, "ENV");
-                    log.debug("Found an OS environment property: {} with 
value: {} to be used.", key, value);
+                    log.debug("Found an OS environment property: {} with 
value: {} to be used.", key, mask(key, value));
                 }
             }
             if (value == null && sysMode == 
PropertiesComponent.SYSTEM_PROPERTIES_MODE_OVERRIDE) {
                 value = System.getProperty(key);
                 if (value != null) {
                     onLookup(key, value, defaultValue, "SYS");
-                    log.debug("Found a JVM system property: {} with value: {} 
to be used.", key, value);
+                    log.debug("Found a JVM system property: {} with value: {} 
to be used.", key, mask(key, value));
                 }
             }
 
             if (value == null && properties != null) {
                 value = properties.lookup(key, defaultValue);
                 if (value != null) {
-                    log.debug("Found property: {} with value: {} to be used.", 
key, value);
+                    log.debug("Found property: {} with value: {} to be used.", 
key, mask(key, value));
                 }
             }
 
@@ -519,7 +523,7 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
                 // custom lookup in spring boot or other runtimes
                 value = customLookup(key);
                 if (value != null) {
-                    log.debug("Found property (custom lookup): {} with value: 
{} to be used.", key, value);
+                    log.debug("Found property (custom lookup): {} with value: 
{} to be used.", key, mask(key, value));
                 }
             }
 
@@ -527,14 +531,14 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
                 value = lookupEnvironmentVariable(key);
                 if (value != null) {
                     onLookup(key, value, defaultValue, "ENV");
-                    log.debug("Found an OS environment property: {} with 
value: {} to be used.", key, value);
+                    log.debug("Found an OS environment property: {} with 
value: {} to be used.", key, mask(key, value));
                 }
             }
             if (value == null && sysMode == 
PropertiesComponent.SYSTEM_PROPERTIES_MODE_FALLBACK) {
                 value = System.getProperty(key);
                 if (value != null) {
                     onLookup(key, value, defaultValue, "SYS");
-                    log.debug("Found a JVM system property: {} with value: {} 
to be used.", key, value);
+                    log.debug("Found a JVM system property: {} with value: {} 
to be used.", key, mask(key, value));
                 }
             }
 
@@ -612,4 +616,8 @@ public class DefaultPropertiesParser implements 
PropertiesParser {
             return value;
         }
     }
+
+    private static Object mask(String key, Object value) {
+        return value != null && key != null && 
SensitiveUtils.containsSensitive(key) ? MASK : value;
+    }
 }
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 0a91a401e08a..513e8aa38e3f 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -51,6 +51,8 @@ import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.OrderedLocationProperties;
 import org.apache.camel.util.OrderedProperties;
 import org.apache.camel.util.PropertiesHelper;
+import org.apache.camel.util.SensitiveUtils;
+import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -320,6 +322,52 @@ public class PropertiesComponent extends ServiceSupport
         return prop;
     }
 
+    private boolean isSensitive(String uri) {
+        // the uri uses a function with sensitive values (such as a vault) or 
refers to a sensitive key
+        for (PropertiesFunction function : 
propertiesFunctionResolver.getFunctions().values()) {
+            if (function.isSensitive() && uri.contains(function.getName() + 
":")) {
+                return true;
+            }
+        }
+        // the keys of the placeholders (without any default value)
+        int start = uri.indexOf(PREFIX_TOKEN);
+        if (start == -1) {
+            return isSensitiveKey(uri);
+        }
+        while (start != -1) {
+            int end = uri.indexOf(SUFFIX_TOKEN, start);
+            if (end == -1) {
+                return false;
+            }
+            if (isSensitiveKey(uri.substring(start + PREFIX_TOKEN.length(), 
end))) {
+                return true;
+            }
+            start = uri.indexOf(PREFIX_TOKEN, end);
+        }
+        return false;
+    }
+
+    private boolean isSensitiveKey(String key) {
+        // the key with a default value (key:default), or the key of a 
function (such as env:DB_PASSWORD)
+        String name = StringHelper.before(key, ":", key);
+        String remainder = StringHelper.after(key, ":");
+        if (remainder != null) {
+            remainder = StringHelper.before(remainder, ":", remainder);
+        }
+        if (!name.isEmpty() && SensitiveUtils.containsSensitive(name)
+                || remainder != null && !remainder.isEmpty() && 
SensitiveUtils.containsSensitive(remainder)) {
+            return true;
+        }
+        // the value of the key is resolved by a function with sensitive 
values (such as {{app.db.conn}} set to a vault)
+        PropertiesResolvedValue resolved = 
defaultPropertiesLookupListener.getProperty(name);
+        return resolved != null && isSensitiveFunction(resolved.source());
+    }
+
+    private boolean isSensitiveFunction(String name) {
+        PropertiesFunction function = name != null ? 
propertiesFunctionResolver.getFunctions().get(name) : null;
+        return function != null && function.isSensitive();
+    }
+
     protected String parseUri(final String uri, PropertiesLookup properties, 
boolean keepUnresolvedOptional) {
         LOG.trace("Parsing uri {}", uri);
 
@@ -351,7 +399,9 @@ public class PropertiesComponent extends ServiceSupport
             // Remove the escape characters if any
             answer = unescape(answer);
         }
-        LOG.trace("Parsed uri {} -> {}", uri, answer);
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Parsed uri {} -> {}", uri, isSensitive(uri) ? "xxxxxx" 
: answer);
+        }
         return answer;
     }
 
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/PropertiesDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/PropertiesDevConsole.java
index d0e6a38a5b21..4af30cdefa44 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/PropertiesDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/PropertiesDevConsole.java
@@ -157,13 +157,18 @@ public class PropertiesDevConsole extends 
AbstractDevConsole {
             source = m.get().source();
             v = m.get().value();
         }
-        boolean sensitive = SensitiveUtils.containsSensitive(k);
+        // a sensitive key, or a value from a function with sensitive values 
(such as a vault)
+        boolean sensitive = SensitiveUtils.containsSensitive(k) || 
isSensitiveFunction(pc, source);
         String value = sensitive ? "xxxxxx" : String.valueOf(v);
         String originalValueOut = originalValue != null ? (sensitive ? 
"xxxxxx" : originalValue) : null;
         Boolean internal = loc != null ? isInternal(loc) : null;
         return new PropertyEntry(k, value, originalValueOut, defaultValue, 
source, loc, internal);
     }
 
+    private static boolean isSensitiveFunction(PropertiesComponent pc, String 
source) {
+        return source != null && pc.hasPropertiesFunction(source) && 
pc.getPropertiesFunction(source).isSensitive();
+    }
+
     private static boolean isInternal(String loc) {
         if (loc == null) {
             return false;
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentMaskSensitiveLogTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentMaskSensitiveLogTest.java
new file mode 100644
index 000000000000..6fae46f2b879
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentMaskSensitiveLogTest.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.properties;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.component.log.ConsumingAppender;
+import org.apache.camel.spi.PropertiesFunction;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class PropertiesComponentMaskSensitiveLogTest extends 
ContextTestSupport {
+
+    private static final String LOGGER = 
"org.apache.camel.component.properties";
+
+    private final List<String> messages = new CopyOnWriteArrayList<>();
+
+    private static class MyVaultFunction implements PropertiesFunction {
+
+        @Override
+        public String getName() {
+            return "myvault";
+        }
+
+        @Override
+        public String apply(String remainder) {
+            return "Vault-" + remainder;
+        }
+
+        @Override
+        public boolean isSensitive() {
+            return true;
+        }
+    }
+
+    private static class MyUpperFunction implements PropertiesFunction {
+
+        @Override
+        public String getName() {
+            return "myupper";
+        }
+
+        @Override
+        public String apply(String remainder) {
+            return remainder.toUpperCase();
+        }
+    }
+
+    @Override
+    @BeforeEach
+    public void setUp() throws Exception {
+        ConsumingAppender.newAppender(LOGGER, 
"PropertiesComponentMaskSensitiveLogTest", Level.TRACE,
+                e -> messages.add(e.getMessage().getFormattedMessage()));
+        super.setUp();
+    }
+
+    @Override
+    @AfterEach
+    public void tearDown() throws Exception {
+        super.tearDown();
+        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        ctx.getConfiguration().removeLogger(LOGGER);
+        ctx.updateLoggers();
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        Properties props = new Properties();
+        props.put("db.password", "Secret-db");
+        props.put("DB_PASSWORD", "Secret-env");
+        props.put("my.apiSecret", "Secret-api");
+        props.put("greeting", "Hello-public");
+        props.put("app.db.conn", "{{myvault:db/conn}}");
+        context.getPropertiesComponent().setInitialProperties(props);
+        context.getPropertiesComponent().addPropertiesFunction(new 
MyVaultFunction());
+        context.getPropertiesComponent().addPropertiesFunction(new 
MyUpperFunction());
+        return context;
+    }
+
+    @Test
+    public void testSensitiveValuesAreMasked() {
+        assertEquals("Vault-db/password", 
context.resolvePropertyPlaceholders("{{myvault:db/password}}"));
+        assertEquals("Secret-db", 
context.resolvePropertyPlaceholders("{{db.password}}"));
+        assertEquals("Secret-env", 
context.resolvePropertyPlaceholders("{{DB_PASSWORD}}"));
+        assertEquals("Secret-api", 
context.resolvePropertyPlaceholders("{{my.apiSecret}}"));
+        assertEquals("jdbc:Secret-db", 
context.resolvePropertyPlaceholders("jdbc:{{db.password}}"));
+        // a vault value by way of an ordinary property
+        assertEquals("Vault-db/conn", 
context.resolvePropertyPlaceholders("{{app.db.conn}}"));
+        // a sensitive key of a function that is not sensitive
+        System.setProperty("DB_PASSWORD", "Secret-sys");
+        try {
+            assertEquals("Secret-sys", 
context.resolvePropertyPlaceholders("{{sys:DB_PASSWORD}}"));
+        } finally {
+            System.clearProperty("DB_PASSWORD");
+        }
+
+        assertFalse(messages.isEmpty());
+        for (String msg : messages) {
+            assertFalse(msg.contains("Vault-"), msg);
+            assertFalse(msg.contains("Secret-"), msg);
+        }
+        assertTrue(messages.stream().anyMatch(m -> m.contains("xxxxxx")));
+    }
+
+    @Test
+    public void testOtherValuesAreLogged() {
+        assertEquals("Hello-public", 
context.resolvePropertyPlaceholders("{{greeting}}"));
+        assertEquals("HELLO", 
context.resolvePropertyPlaceholders("{{myupper:hello}}"));
+
+        assertTrue(messages.stream().anyMatch(m -> 
m.contains("Hello-public")));
+        assertTrue(messages.stream().anyMatch(m -> m.contains("HELLO")));
+    }
+}
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java 
b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
index 27ee2244656f..005f3e82cc31 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SensitiveUtils.java
@@ -49,6 +49,7 @@ public final class SensitiveUtils {
                     "api_secret",
                     "apikey",
                     "apipassword",
+                    "apisecret",
                     "apiuser",
                     "apiusername",
                     "authenticationtoken",
@@ -73,6 +74,7 @@ public final class SensitiveUtils {
                     "databasesslkeystorepassword",
                     "databasesslpassword",
                     "databasessltruststorepassword",
+                    "db_password",
                     "emailaddress",
                     "functionkey",
                     "hostkey",
@@ -156,6 +158,7 @@ public final class SensitiveUtils {
                                                     + "|\\Qapi_secret\\E"
                                                     + "|\\Qapikey\\E"
                                                     + "|\\Qapipassword\\E"
+                                                    + "|\\Qapisecret\\E"
                                                     + "|\\Qapiuser\\E"
                                                     + "|\\Qapiusername\\E"
                                                     + 
"|\\Qauthenticationtoken\\E"
@@ -180,6 +183,7 @@ public final class SensitiveUtils {
                                                     + 
"|\\Qdatabasesslkeystorepassword\\E"
                                                     + 
"|\\Qdatabasesslpassword\\E"
                                                     + 
"|\\Qdatabasessltruststorepassword\\E"
+                                                    + "|\\Qdb_password\\E"
                                                     + "|\\Qemailaddress\\E"
                                                     + "|\\Qfunctionkey\\E"
                                                     + "|\\Qhostkey\\E"
diff --git 
a/core/camel-util/src/test/java/org/apache/camel/util/SensitiveUtilsTest.java 
b/core/camel-util/src/test/java/org/apache/camel/util/SensitiveUtilsTest.java
index 78a604198124..ab496424dd0f 100644
--- 
a/core/camel-util/src/test/java/org/apache/camel/util/SensitiveUtilsTest.java
+++ 
b/core/camel-util/src/test/java/org/apache/camel/util/SensitiveUtilsTest.java
@@ -30,6 +30,8 @@ class SensitiveUtilsTest {
         
assertThat(SensitiveUtils.containsSensitive("authorizationtoken")).isTrue();
         assertThat(SensitiveUtils.containsSensitive("clientsecret")).isTrue();
         assertThat(SensitiveUtils.containsSensitive("passphrase")).isTrue();
+        assertThat(SensitiveUtils.containsSensitive("DB_PASSWORD")).isTrue();
+        assertThat(SensitiveUtils.containsSensitive("app.apiSecret")).isTrue();
         assertThat(SensitiveUtils.containsSensitive("password")).isTrue();
         
assertThat(SensitiveUtils.containsSensitive("sasljaasconfig")).isTrue();
         
assertThat(SensitiveUtils.containsSensitive("sasl-jaas-config")).isTrue();
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSensitizeHelper.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSensitizeHelper.java
index 5efc85fb5c19..c8074a0fd34d 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSensitizeHelper.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSensitizeHelper.java
@@ -83,7 +83,8 @@ public class UpdateSensitizeHelper extends 
AbstractGeneratorMojo {
     // OpenAI api-key header, and "authorization" covers the standard 
Authorization header.
     private static final String[] EXTRA_KEYS
             = new String[] {
-                    "apipassword", "apiuser", "apiusername", "api_key", 
"api-key", "api_secret", "authorization",
+                    "apipassword", "apisecret", "apiuser", "apiusername", 
"api_key", "api-key", "api_secret", "authorization",
+                    "db_password",
                     SECRET, "keystorePassword" };
 
     // extra security options from camel-main properties that are not in 
component JSON files

Reply via email to