Dhairya-007 opened a new pull request, #29705:
URL: https://github.com/apache/camel/pull/29705
## Problem
Four classes write credentials into their `toString()` in clear:
| component | class | leaked |
| --- | --- | --- |
| camel-zendesk | `ZendeskConfiguration` | `password`, `token`, `oauthToken`
|
| camel-kubernetes | `KubernetesConfiguration` | `password`, `oauthToken`,
`caCertData`, `clientCertData`, `clientKeyData`, `clientKeyPassphrase` |
| camel-smpp | `SmppConfiguration` | `password`, `httpProxyPassword` |
| camel-huaweicloud-dms | `CreateInstanceRequestBody` | `password`,
`kafkaManagerPassword` |
```java
// ZendeskConfiguration
return String.format(
"ZendeskConfiguration:[methodName=%s, serverUrl=%s, username=%s,
password=%s, token=%s, oauthToken=%s]",
methodName, serverUrl, username, password, token, oauthToken);
```
Every one of those options is marked `secret: true` in the component's
**own** generated metadata — I checked `zendesk.json`, `kubernetes-pods.json`
and `smpp.json` — and `clientKeyData` is a private key. A configuration's
`toString()` is not a private detail: it reaches a log file, a JMX attribute, a
dev-console dump or an exception message without anyone deciding to publish it,
so a secret flag has to hold there too.
Camel already does this elsewhere, which is what makes these look like
oversights rather than choices:
```java
// camel-netty-http HttpPrincipal
// do not display the password
return "HttpPrincipal[" + username + "]";
// camel-snmp SnmpEndpoint
// only show address to avoid user and password details to be shown
return "snmp://" + serverAddress;
```
## Fix
Mask the credential material with `xxxxxx` — the mask `URISupport` already
uses when it sanitizes a URI, chosen there because it also works well with JMX
— and only when the value is non-null, so the line still says whether a
credential was configured at all:
```java
private static String mask(Object secret) {
return secret != null ? "xxxxxx" : "null";
}
```
What *points at* the material stays readable — `masterUrl`, `serverUrl`,
`username`, `systemId`, `caCertFile`, `clientKeyFile` — so the output is still
useful for diagnosis. The distinction is deliberate: a path to a key file is
not the key.
`ZendeskConfiguration.hashCode()` is `toString().hashCode()`, so it becomes
coarser: two configurations differing only in a password now hash alike. That
is still consistent with `equals`, which keeps comparing the real values.
`SmppConfigurationTest.toStringShouldListAllInstanceVariables` asserts the
whole string with `password=null`, and still passes unchanged, because a null
credential is still printed as `null`.
## Tests
- `SmppConfigurationTest.toStringShouldNotLeakCredentials` — a set
`password` and `httpProxyPassword` are masked, `systemId` is not.
- `ZendeskConfigurationTest` — the three credentials are masked, `serverUrl`
is not, and an unset credential still shows as `null`.
- `KubernetesConfigurationTest` — the six credentials are masked, while
`clientKeyFile` and `masterUrl` stay readable.
Each asserts on the secret's literal value, so it fails on `main`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]