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

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git


The following commit(s) were added to refs/heads/master by this push:
     new 144367bb6 Make sure we can't register a fake SOAP Body for lookup 
(#686)
144367bb6 is described below

commit 144367bb6c76ec4024d6e9c3f3405fd31e258ab7
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Sep 10 20:30:45 2026 +0100

    Make sure we can't register a fake SOAP Body for lookup (#686)
    
    * Updating replay cache docs
    
    * Make sure we can't register a fake SOAP Body for lookup
---
 THREAT-MODEL.md                                     |  4 ++--
 src/site/asciidoc/config.adoc                       | 15 +++++++++------
 src/site/asciidoc/newfeatures20.adoc                | 21 ++++++++++++++-------
 src/site/asciidoc/wss4j20.adoc                      | 15 +++++++++------
 .../wss4j/dom/callback/DOMCallbackLookup.java       |  8 ++++++++
 5 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/THREAT-MODEL.md b/THREAT-MODEL.md
index 8ee4a6e16..5111954d2 100644
--- a/THREAT-MODEL.md
+++ b/THREAT-MODEL.md
@@ -301,7 +301,7 @@ subset:
 | `ENABLE_REVOCATION` | `false` *(documented)* | optional CRL checking | 
inbound certificate revocation |
 | `ENABLE_SIGNATURE_CONFIRMATION` | `false` *(documented)* | tunable | enables 
WS-Security SignatureConfirmation flow |
 | `VALIDATE_SAML_SUBJECT_CONFIRMATION` | `true` *(documented)* | hardened | 
inbound SAML SubjectConfirmation validation |
-| `NONCE_CACHE_INSTANCE` / `TIMESTAMP_CACHE_INSTANCE` / 
`SAML_ONE_TIME_USE_CACHE_INSTANCE` | `EHCacheReplayCache` *(documented)* | 
replay protection on by default | replay cache for UsernameToken nonces, 
Timestamps, SAML OneTimeUse |
+| `NONCE_CACHE_INSTANCE` / `TIMESTAMP_CACHE_INSTANCE` / 
`SAML_ONE_TIME_USE_CACHE_INSTANCE` | No WSS4J-core default; 
`EHCacheReplayCache` supplied by integrations such as CXF *(documented)* | 
replay protection on by default for CXF inbound recipient messages; direct 
WSS4J callers must configure a cache | replay cache for UsernameToken nonces, 
Timestamps, SAML OneTimeUse |
 | `PASSWORD_ENCRYPTOR_INSTANCE` | `JasyptPasswordEncryptor` *(documented)* | 
tunable | decryption of encrypted passwords in Crypto properties files |
 | `merlin.keystore.password` | `"security"` *(documented: 
`src/site/asciidoc/config.adoc`)* | **maintainer ruling required** — this is a 
*default for the property file*; production deployments override *(inferred — 
§14 Q12)* | Merlin keystore password |
 | `merlin.truststore.password` | `"changeit"` *(documented)* | dev default | 
Merlin truststore password |
@@ -437,7 +437,7 @@ on each is captured in §14 Q10–Q11.
 
 ### P5 — Replay protection on inbound UsernameToken nonces, Timestamps, and 
SAML2 OneTimeUse assertions
 
-- **Condition**: replay-cache is enabled (default `EHCacheReplayCache`);
+- **Condition**: replay-cache is enabled (for example, the CXF inbound 
recipient default `EHCacheReplayCache`);
   inbound message carries the required `wsu:Created` / `Nonce` /
   SAML2 `OneTimeUse` condition.
 - **Violation symptom**: an inbound envelope identical to one already
diff --git a/src/site/asciidoc/config.adoc b/src/site/asciidoc/config.adoc
index 36a3b25d8..210dfb337 100644
--- a/src/site/asciidoc/config.adoc
+++ b/src/site/asciidoc/config.adoc
@@ -302,13 +302,16 @@ verification of the certificate chain associated with the 
certificate.
 SIG_SUBJECT_CERT_CONSTRAINTS and SIG_ISSUER_CERT_CONSTRAINTS configuration 
tags. The default is ",".
  * *WSS4J 2.0.0* VALIDATOR_MAP (validatorMap) - A map of QName, Object 
(Validator) instances to be used to validate
 tokens identified by their QName.
- * *WSS4J 2.0.0* NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache 
instance used to cache UsernameToken nonces. The default
-instance that is used is the EHCacheReplayCache.
- * *WSS4J 2.0.0* TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - A 
ReplayCache instance used to cache Timestamp Created Strings. The default
-instance that is used is the EHCacheReplayCache.
+ * *WSS4J 2.0.0* NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache 
instance used to cache UsernameToken nonces. WSS4J core
+does not create a default ReplayCache. Integrations such as Apache CXF 
configure an EHCacheReplayCache by default for inbound
+recipient messages; applications using WSS4J directly must configure a 
ReplayCache to enable replay detection.
+ * *WSS4J 2.0.0* TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - 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 by default for inbound
+recipient messages; applications using WSS4J directly must configure a 
ReplayCache to enable replay detection.
  * *WSS4J 2.0.0* SAML_ONE_TIME_USE_CACHE_INSTANCE 
(samlOneTimeUseCacheInstance) - 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.
+the token contains a OneTimeUse Condition). WSS4J core does not create a 
default ReplayCache. Integrations such as Apache CXF
+configure an EHCacheReplayCache by default for inbound recipient messages; 
applications using WSS4J directly must configure a
+ReplayCache to enable replay detection.
  * *WSS4J 2.0.0* PASSWORD_ENCRYPTOR_INSTANCE (passwordEncryptorInstance) - A 
PasswordEncryptor instance used to decrypt encrypted passwords in Crypto
 properties files. The default is the JasyptPasswordEncryptor.
  * *WSS4J 2.0.0* DERIVED_TOKEN_REFERENCE (derivedTokenReference) - This 
controls how deriving tokens are referenced.
diff --git a/src/site/asciidoc/newfeatures20.adoc 
b/src/site/asciidoc/newfeatures20.adoc
index 38b153d4c..b4977204d 100644
--- a/src/site/asciidoc/newfeatures20.adoc
+++ b/src/site/asciidoc/newfeatures20.adoc
@@ -74,26 +74,33 @@ guard against replay attacks for the following scenarios:
  * SAML OneTimeUse Assertions
 
 However, replay attack detection was not "switched on" by default in WSS4J
-1.6.x. In WSS4J 2.0.x, replay attack detection is enabled by default using
-an implementation of the "ReplayCache" interface based on EhCache. The 
-following configuration tags can be used to configure caching:
+1.6.x. In WSS4J 2.0.x integrations such as Apache CXF enable replay attack
+detection by default using an implementation of the "ReplayCache" interface
+based on EhCache. WSS4J core does not create ReplayCache instances itself.
+Integrations such as
+Apache CXF enable replay attack detection by default for inbound recipient
+messages and provide a ReplayCache. Applications using WSS4J directly must
+configure a ReplayCache. The following configuration tags can be used to
+configure caching:
 
  * ConfigurationConstants.TIMESTAMP_CACHE_INSTANCE ("timestampCacheInstance"):
 This holds a reference to a ReplayCache instance used to cache Timestamp
-Created Strings. The default instance that is used is the EHCacheReplayCache.
+Created Strings. WSS4J core does not create a default instance; integrations
+such as Apache CXF provide one for inbound recipient messages.
  * ConfigurationConstants.ENABLE_TIMESTAMP_CACHE ("enableTimestampCache"):
 Whether to cache Timestamp Created Strings (these are only cached in
 conjunction with a message Signature). The default value is "true".
  * ConfigurationConstants.NONCE_CACHE_INSTANCE ("nonceCacheInstance"): This
 holds a reference to a ReplayCache instance used to cache UsernameToken
-nonces. The default instance that is used is the EHCacheReplayCache.
+nonces. WSS4J core does not create a default instance; integrations such as
+Apache CXF provide one for inbound recipient messages.
  * ConfigurationConstants.ENABLE_NONCE_CACHE ("enableNonceCache"): Whether to
 cache UsernameToken nonces. The default value is "true".
  * ConfigurationConstants. SAML_ONE_TIME_USE_CACHE_INSTANCE
 ("samlOneTimeUseCacheInstance"): 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.
+OneTimeUse Condition). WSS4J core does not create a default instance;
+integrations such as Apache CXF provide one for inbound recipient messages.
  * ConfigurationConstants.ENABLE_SAML_ONE_TIME_USE_CACHE
 ("enableSamlOneTimeUseCache"):  Whether to cache SAML2 Token Identifiers, if
 the token contains a "OneTimeUse" Condition. The default value is "true".
diff --git a/src/site/asciidoc/wss4j20.adoc b/src/site/asciidoc/wss4j20.adoc
index ef8f819a5..bfea4d630 100644
--- a/src/site/asciidoc/wss4j20.adoc
+++ b/src/site/asciidoc/wss4j20.adoc
@@ -191,13 +191,16 @@ exist in the request.
 Transport algorithm for encryption. The default is mgfsha1.
  * VALIDATOR_MAP (validatorMap) - A map of QName, Object (Validator) instances 
to be used to validate
 tokens identified by their QName.
- * NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache instance used to 
cache UsernameToken nonces. The default
-instance that is used is the EHCacheReplayCache.
- * TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - A ReplayCache instance 
used to cache Timestamp Created Strings. The default
-instance that is used is the EHCacheReplayCache.
+ * NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache instance used to 
cache UsernameToken nonces. WSS4J core does not
+create a default ReplayCache. Integrations such as Apache CXF configure an 
EHCacheReplayCache by default for inbound recipient
+messages; applications using WSS4J directly must configure a ReplayCache to 
enable replay detection.
+ * TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - 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 by default for inbound
+recipient messages; applications using WSS4J directly must configure a 
ReplayCache to enable replay detection.
  * SAML_ONE_TIME_USE_CACHE_INSTANCE (samlOneTimeUseCacheInstance) - 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.
+the token contains a OneTimeUse Condition). WSS4J core does not create a 
default ReplayCache. Integrations such as Apache CXF
+configure an EHCacheReplayCache by default for inbound recipient messages; 
applications using WSS4J directly must configure a
+ReplayCache to enable replay detection.
  * PASSWORD_ENCRYPTOR_INSTANCE (passwordEncryptorInstance) - A 
PasswordEncryptor instance used to decrypt encrypted passwords in Crypto
 properties files. The default is the JasyptPasswordEncryptor.
  * DERIVED_TOKEN_REFERENCE (derivedTokenReference) - This controls how 
deriving tokens are referenced.
diff --git 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/callback/DOMCallbackLookup.java
 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/callback/DOMCallbackLookup.java
index 7a9cf38d8..47bb67bc3 100644
--- 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/callback/DOMCallbackLookup.java
+++ 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/callback/DOMCallbackLookup.java
@@ -96,6 +96,14 @@ public class DOMCallbackLookup implements CallbackLookup {
         Element foundElement =
             XMLUtils.findElementById(doc.getDocumentElement(), idToMatch, 
checkMultipleElements);
         if (foundElement != null) {
+            // Reject a Body-named element found elsewhere in the document 
that is not the
+            // live SOAP Body, to prevent a signature wrapping attack that 
relocates a signed
+            // Body and resolves the reference to the stale copy instead of 
the real one
+            if (bodyElement != null && foundElement != bodyElement
+                && WSConstants.ELEM_BODY.equals(foundElement.getLocalName())
+                && 
bodyElement.getNamespaceURI().equals(foundElement.getNamespaceURI())) {
+                return null;
+            }
             if (context != null) {
                 if (foundElement.hasAttributeNS(WSConstants.WSU_NS, "Id")
                     && 
idToMatch.equals(foundElement.getAttributeNS(WSConstants.WSU_NS, "Id"))) {

Reply via email to