You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2026/09/18 16:48:35 UTC
(ws-wss4j) branch 3_0_x-fixes updated (2a6708774 -> ca8f52da7)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a change to branch 3_0_x-fixes
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
from 2a6708774 Updating Neethi to 3.2.4 (#710)
new e72b7f319 Javadoc updates
new ca8f52da7 Redact passwords from UsernameToken toString (#711)
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../wss4j/common/ConfigurationConstants.java | 18 ++--
.../wss4j/dom/message/token/UsernameToken.java | 13 ++-
.../message/token/UsernameTokenToStringTest.java | 118 +++++++++++++++++++++
3 files changed, 141 insertions(+), 8 deletions(-)
create mode 100644 ws-security-dom/src/test/java/org/apache/wss4j/dom/message/token/UsernameTokenToStringTest.java
(ws-wss4j) 01/02: Javadoc updates
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3_0_x-fixes
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
commit e72b7f319f1b0bc6274b07c5e5d286a600289748
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Fri Sep 18 17:17:14 2026 +0100
Javadoc updates
---
.../apache/wss4j/common/ConfigurationConstants.java | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java b/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java
index 9461fcb2c..cbff5719e 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java
@@ -956,21 +956,27 @@ public class ConfigurationConstants {
public static final String VALIDATOR_MAP = "validatorMap";
/**
- * This holds a reference to a ReplayCache instance used to cache UsernameToken nonces. The
- * default instance that is used is the EHCacheReplayCache.
+ * This holds a reference to a ReplayCache instance used to cache UsernameToken nonces.
+ * WSS4J core does not create a default ReplayCache: integrations such as Apache CXF configure
+ * an EHCacheReplayCache for inbound recipient messages, and applications using WSS4J directly
+ * must configure one themselves for replay detection to take place at all.
*/
public static final String NONCE_CACHE_INSTANCE = "nonceCacheInstance";
/**
- * This holds a reference to a ReplayCache instance used to cache Timestamp Created Strings. The
- * default instance that is used is the EHCacheReplayCache.
+ * This holds a reference to a ReplayCache instance used to cache Timestamp Created Strings.
+ * WSS4J core does not create a default ReplayCache: integrations such as Apache CXF configure
+ * an EHCacheReplayCache for inbound recipient messages, and applications using WSS4J directly
+ * must configure one themselves for replay detection to take place at all.
*/
public static final String TIMESTAMP_CACHE_INSTANCE = "timestampCacheInstance";
/**
* This holds a reference to a ReplayCache instance used to cache SAML2 Token Identifier
- * Strings (if the token contains a OneTimeUse Condition). The default instance that is
- * used is the EHCacheReplayCache.
+ * Strings (if the token contains a OneTimeUse Condition). WSS4J core does not create a default
+ * ReplayCache: integrations such as Apache CXF configure an EHCacheReplayCache for inbound
+ * recipient messages, and applications using WSS4J directly must configure one themselves for
+ * replay detection to take place at all.
*/
public static final String SAML_ONE_TIME_USE_CACHE_INSTANCE = "samlOneTimeUseCacheInstance";
(ws-wss4j) 02/02: Redact passwords from UsernameToken toString (#711)
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3_0_x-fixes
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
commit ca8f52da755dcc334b03a8f6d00f198a3089cb08
Author: Colm O hEigeartaigh <co...@users.noreply.github.com>
AuthorDate: Fri Sep 18 17:41:56 2026 +0100
Redact passwords from UsernameToken toString (#711)
---
.../wss4j/dom/message/token/UsernameToken.java | 13 ++-
.../message/token/UsernameTokenToStringTest.java | 118 +++++++++++++++++++++
2 files changed, 129 insertions(+), 2 deletions(-)
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
index 71c2c7698..db47b5335 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
@@ -544,12 +544,21 @@ public class UsernameToken {
}
/**
- * Returns the string representation of the token.
+ * Returns the string representation of the token, with the content of any wsse:Password
+ * redacted.
*
* @return a XML string representation
*/
public String toString() {
- return DOM2Writer.nodeToString(element);
+ Element redacted = (Element)element.cloneNode(true);
+ Element passwordElement =
+ XMLUtils.getDirectChildElement(
+ redacted, WSConstants.PASSWORD_LN, WSConstants.WSSE_NS
+ );
+ if (passwordElement != null) {
+ passwordElement.setTextContent("***");
+ }
+ return DOM2Writer.nodeToString(redacted);
}
/**
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/token/UsernameTokenToStringTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/token/UsernameTokenToStringTest.java
new file mode 100644
index 000000000..51f063af3
--- /dev/null
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/token/UsernameTokenToStringTest.java
@@ -0,0 +1,118 @@
+/**
+ * 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.wss4j.dom.message.token;
+
+import org.apache.wss4j.common.util.SOAPUtil;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.engine.WSSConfig;
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Document;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * A UsernameToken object reaches a log line or an exception message far more readily than a
+ * password does by any other route, so toString() must not hand the password over with it.
+ */
+public class UsernameTokenToStringTest {
+
+ private static final String PASSWORD = "SuperSecretPassword123";
+
+ public UsernameTokenToStringTest() {
+ WSSConfig.init();
+ }
+
+ @Test
+ public void testPlaintextPasswordIsRedacted() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ UsernameToken usernameToken = new UsernameToken(true, doc, WSConstants.PASSWORD_TEXT);
+ usernameToken.setName("bob");
+ usernameToken.setPassword(PASSWORD);
+
+ String serialized = usernameToken.toString();
+
+ assertFalse(serialized.contains(PASSWORD),
+ "toString() must not disclose the password: " + serialized);
+ assertTrue(serialized.contains("bob"),
+ "toString() should still identify the token: " + serialized);
+ assertTrue(serialized.contains("***"),
+ "the password element should still be there, redacted: " + serialized);
+ }
+
+ /**
+ * A password digest is not the password, but it is the value an offline attack runs against,
+ * so it is withheld in the same way.
+ */
+ @Test
+ public void testDigestPasswordIsRedacted() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ // the PASSWORD_DIGEST constructor adds the Nonce and Created itself
+ UsernameToken usernameToken = new UsernameToken(true, doc, WSConstants.PASSWORD_DIGEST);
+ usernameToken.setName("bob");
+ usernameToken.setPassword(PASSWORD);
+
+ String digest = usernameToken.getPassword();
+ String serialized = usernameToken.toString();
+
+ assertFalse(serialized.contains(PASSWORD), "toString() disclosed the password");
+ assertFalse(serialized.contains(digest),
+ "toString() must not disclose the password digest: " + serialized);
+ assertTrue(serialized.contains("***"), serialized);
+ }
+
+ /**
+ * Redaction happens on a copy: the token itself must be untouched, or the password would be
+ * destroyed by the act of logging it.
+ */
+ @Test
+ public void testRedactionDoesNotAlterTheToken() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ UsernameToken usernameToken = new UsernameToken(true, doc, WSConstants.PASSWORD_TEXT);
+ usernameToken.setName("bob");
+ usernameToken.setPassword(PASSWORD);
+
+ usernameToken.toString();
+
+ assertEquals(PASSWORD, usernameToken.getPassword(),
+ "toString() must not modify the token it was called on");
+ assertEquals(PASSWORD,
+ usernameToken.getElement().getElementsByTagNameNS(
+ WSConstants.WSSE_NS, WSConstants.PASSWORD_LN).item(0).getTextContent(),
+ "toString() must not modify the underlying element");
+ }
+
+ /**
+ * A UsernameToken carrying no password at all - the key derivation case - still serialises.
+ */
+ @Test
+ public void testTokenWithoutPasswordIsUnaffected() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ UsernameToken usernameToken = new UsernameToken(true, doc, null);
+ usernameToken.setName("bob");
+
+ String serialized = usernameToken.toString();
+
+ assertTrue(serialized.contains("bob"), serialized);
+ assertFalse(serialized.contains("***"),
+ "nothing to redact, so nothing should be redacted: " + serialized);
+ }
+}