oscerd commented on code in PR #26726:
URL: https://github.com/apache/camel/pull/26726#discussion_r4104282708


##########
components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java:
##########
@@ -382,6 +387,41 @@ public void configure() {
         };
     }
 
+    RouteBuilder createEnforceReferenceCoverageRoute() {
+        return new RouteBuilder() {
+            public void configure() {
+                
onException(XmlSignatureException.class).handled(true).to("mock:enforceCoverageException");
+                from("direct:enforceCoverage")
+                        
.to("xmlsecurity-sign:enforceCoverage?keyAccessor=#keyAccessorDefault"
+                            + "&xpathsToIdAttributes=#xpathsToIdAttributes"
+                            + 
"&schemaResourceUri=org/apache/camel/component/xmlsecurity/Test.xsd&signatureId=&clearHeaders=false")
+                        
.to("xmlsecurity-verify:enforceCoverage?keySelector=#keySelectorDefault"
+                            + 
"&schemaResourceUri=org/apache/camel/component/xmlsecurity/Test.xsd"
+                            + "&xmlSignature2Message=#enforceCoverageMapper")
+                        .to("mock:enforceCoverageResult");
+            }
+        };
+    }
+
+    @Test
+    void enforceReferenceCoverageRejectsASignatureCoveringOnlyASubElement() 
throws Exception {
+        // a detached signature legitimately covers a sub-element while the 
whole document is emitted - the same shape
+        // as an XML signature wrapping attack. With enforceReferenceCoverage 
on, the default output-node search must
+        // refuse to emit the uncovered document element. This drives the 
check through mapToMessage, not in isolation.
+        String detachedPayload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                                 + "<ns:root xmlns:ns=\"http://test\";><a 
ID=\"myID\"><b>bValue</b></a></ns:root>";
+
+        MockEndpoint exceptionMock = 
getMockEndpoint("mock:enforceCoverageException");
+        exceptionMock.expectedMessageCount(1);
+        MockEndpoint resultMock = 
getMockEndpoint("mock:enforceCoverageResult");
+        resultMock.expectedMessageCount(0);
+
+        TestSupport.sendBody(this.template, "direct:enforceCoverage", 
detachedPayload,
+                
Collections.singletonMap(XmlSignatureConstants.HEADER_CONTENT_REFERENCE_URI, 
(Object) "#myID"));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }

Review Comment:
   Added in fd17dc0: `enforceReferenceCoverageAcceptsAWholeDocumentReference`, 
the acceptance counterpart to the rejection test. It signs an enveloped 
signature whose reference covers the whole document (URI="" with the 
enveloped-signature transform) and runs it through the full sign → verify → 
mapToMessage pipeline with `enforceReferenceCoverage=true`, asserting the 
exchange reaches `mock:enforceCoverageResult`.
   
   I used a dedicated enveloped route (`direct:enforceCoverageAccept`) rather 
than the existing `direct:enforceCoverage`, because the latter is a detached 
signature keyed on `xpathsToIdAttributes` and structurally signs a sub-element 
by id, so it can't produce a clean whole-document reference.
   
   To confirm the test actually exercises the wiring (not just the predicate), 
I temporarily made the coverage check reject unconditionally: the new 
acceptance test then fails (`mock:enforceCoverageResult` receives 0) while the 
rejection test still passes — so the two tests together pin both directions of 
the `if (enforceReferenceCoverage)` guard end-to-end. Full-reactor `mvn clean 
install -DskipTests` is green.



-- 
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]

Reply via email to