[java-opensaml] 02/02: OSJ-428: SAML MessageDecoders should enforce that message parameters...

Codeberg noreply at shibboleth.net
Mon Dec 15 07:08:48 UTC 2025


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-opensaml.

View the commit online:
https://codeberg.org/Shibboleth/java-opensaml/commit/6540aaddf03a604000e69725accb4a85649de407

commit 6540aaddf03a604000e69725accb4a85649de407
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Mon Dec 15 01:35:39 2025 -0500

    OSJ-428: SAML MessageDecoders should enforce that message parameters...
    
    SAML MessageDecoders should enforce that message parameters contain
    correct message type.
---
 .../saml/common/binding/SAMLBindingSupport.java    | 59 +++++++++++++
 .../binding/decoding/impl/HTTPPostDecoder.java     |  1 +
 .../binding/decoding/impl/HTTPPostDecoder.java     | 16 +++-
 .../decoding/impl/HTTPRedirectDeflateDecoder.java  |  1 +
 .../impl/SAMLBindingSupportXMLObjectTests.java     | 96 ++++++++++++++++++++++
 .../binding/decoding/impl/HTTPPostDecoderTest.java | 19 +++++
 .../binding/decoding/impl/HTTPPostDecoderTest.java | 30 +++++++
 .../impl/HTTPPostSimpleSignDecoderTest.java        | 29 +++++++
 .../impl/HTTPRedirectDeflateDecoderTest.java       | 28 ++++++-
 9 files changed, 275 insertions(+), 4 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/SAMLBindingSupport.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/SAMLBindingSupport.java
index dae771756..d4db8f8c3 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/SAMLBindingSupport.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/binding/SAMLBindingSupport.java
@@ -25,12 +25,15 @@ import javax.annotation.Nullable;
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.messaging.MessageException;
 import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.decoder.MessageDecodingException;
 import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.common.SignableSAMLObject;
 import org.opensaml.saml.common.messaging.context.SAMLBindingContext;
 import org.opensaml.saml.common.messaging.context.SAMLEndpointContext;
 import org.opensaml.saml.common.messaging.context.SAMLMessageReceivedEndpointContext;
 import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+import org.opensaml.saml.saml1.core.ResponseAbstractType;
+import org.opensaml.saml.saml2.core.StatusResponseType;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.slf4j.Logger;
 
@@ -410,5 +413,61 @@ public final class SAMLBindingSupport {
         return Constraint.isGreaterThanOrEqual(0, value, 
                 "Input value was too large, resulting in a negative 16-bit short");
     }
+    
+    /**
+     * Evaluate a SAML 1 message {@link SAMLObject} as to whether it is the expected message type (request vs response).
+     * 
+     * @param expectRequest true if a SAML 1 request is expected (an instance of
+     *                      {@link org.opensaml.saml.saml1.core.RequestAbstractType},
+     *                      false if a SAML 1 response is expected (an instance of
+     *                      {@link org.opensaml.saml.saml1.core.ResponseAbstractType}
+     * @param message the message to evaluate
+     * 
+     * @throws MessageDecodingException  if the message being evaluated is not the expected type
+     */
+    public static void checkSAML1MessageType(final boolean expectRequest, @Nonnull final SAMLObject message)
+            throws MessageDecodingException {
+        Constraint.isNotNull(message, "SAML 1 message cannot be null");
+
+        if (expectRequest) {
+            if (! org.opensaml.saml.saml1.core.RequestAbstractType.class.isInstance(message)) {
+                throw new MessageDecodingException("Expected a SAML 1 request message, but saw: " 
+                        + message.getClass().getName());
+            }
+        } else { 
+            if (! ResponseAbstractType.class.isInstance(message)){ 
+                throw new MessageDecodingException("Expected a SAML 1 response message, but saw: " 
+                        + message.getClass().getName());
+            }
+        }
+    }
+
+    /**
+     * Evaluate a SAML 2 message {@link SAMLObject} as to whether it is the expected message type (request vs response).
+     * 
+     * @param expectRequest true if a SAML 2 request is expected (an instance of
+     *                      {@link org.opensaml.saml.saml2.core.RequestAbstractType},
+     *                      false if a SAML 2 response is expected (an instance of
+     *                      {@link org.opensaml.saml.saml1.core.ResponseAbstractType}
+     * @param message the message to evaluate
+     * 
+     * @throws MessageDecodingException  if the message being evaluated is not the expected type
+     */
+    public static void checkSAML2MessageType(final boolean expectRequest, @Nonnull final SAMLObject message)
+            throws MessageDecodingException {
+        Constraint.isNotNull(message, "SAML 2 message cannot be null");
+
+        if (expectRequest) {
+            if (! org.opensaml.saml.saml2.core.RequestAbstractType.class.isInstance(message)) {
+                throw new MessageDecodingException("Expected a SAML 2 request message, but saw: " 
+                        + message.getClass().getName());
+            }
+        } else { 
+            if (! StatusResponseType.class.isInstance(message)){ 
+                throw new MessageDecodingException("Expected a SAML 2 response message, but saw: " 
+                        + message.getClass().getName());
+            }
+        }
+    }
 
 }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoder.java
index 37fe25f0a..fb965a7d2 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoder.java
@@ -93,6 +93,7 @@ public class HTTPPostDecoder extends BaseSAMLHttpServletRequestDecoder implement
             final byte[] decodedBytes = Base64Support.decode(base64Message);
             
             final SAMLObject inboundMessage = (SAMLObject) unmarshallMessage(new ByteArrayInputStream(decodedBytes));
+            SAMLBindingSupport.checkSAML1MessageType(false, inboundMessage);
             messageContext.setMessage(inboundMessage);
             log.debug("Decoded SAML message");
     
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoder.java
index f74d0668a..466d07c18 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoder.java
@@ -38,6 +38,7 @@ import jakarta.servlet.http.HttpServletRequest;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.codec.Base64Support;
 import net.shibboleth.shared.codec.DecodingException;
+import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
 /** Message decoder implementing the SAML 2.0 HTTP POST binding. */
@@ -87,8 +88,13 @@ public class HTTPPostDecoder extends BaseSAMLHttpServletRequestDecoder implement
 
         // The default impl is a ByteArrayInputStream, which really doesn't need to be closed.  But this could
         // be overridden, so be safe and make sure it gets closed.  Also for style and consistency.
-        try (final InputStream base64DecodedMessage = getBase64DecodedMessage(request)) {
+        final Pair<InputStream,String> messageData = getBase64DecodedMessage(request);
+        try (final InputStream base64DecodedMessage = messageData.getFirst()) {
+            assert base64DecodedMessage != null;
             final SAMLObject inboundMessage = (SAMLObject) unmarshallMessage(base64DecodedMessage);
+            final String samlMessageParamName = messageData.getSecond();
+            assert samlMessageParamName != null;
+            SAMLBindingSupport.checkSAML2MessageType("SAMLRequest".equals(samlMessageParamName), inboundMessage);
             messageContext.setMessage(inboundMessage);
             log.debug("Decoded SAML message");
         } catch (final IOException e) {
@@ -110,12 +116,16 @@ public class HTTPPostDecoder extends BaseSAMLHttpServletRequestDecoder implement
      * @throws MessageDecodingException thrown if the message does not contain a base64 encoded SAML message, 
      *                                      or the message can not be base64-decoded.
      */
-    @Nonnull protected InputStream getBase64DecodedMessage(@Nonnull final HttpServletRequest request)
+    @Nonnull protected Pair<InputStream,String> getBase64DecodedMessage(@Nonnull final HttpServletRequest request)
             throws MessageDecodingException {
         log.debug("Getting Base64 encoded message from request");
+        String samlMessageParamName = null;
         String encodedMessage = request.getParameter("SAMLRequest");
         if (Strings.isNullOrEmpty(encodedMessage)) {
             encodedMessage = request.getParameter("SAMLResponse");
+            samlMessageParamName = "SAMLResponse";
+        } else {
+            samlMessageParamName = "SAMLRequest";
         }
 
         if (Strings.isNullOrEmpty(encodedMessage)) {
@@ -129,7 +139,7 @@ public class HTTPPostDecoder extends BaseSAMLHttpServletRequestDecoder implement
             log.trace("Base64 decoding SAML message:\n{}", encodedMessage);
             final byte[] decodedBytes = Base64Support.decode(encodedMessage);            
             log.trace("Decoded SAML message:\n{}", new String(decodedBytes));
-            return new ByteArrayInputStream(decodedBytes);
+            return new Pair<>(new ByteArrayInputStream(decodedBytes), samlMessageParamName);
             
         } catch (final DecodingException e) {        
             log.error("Unable to Base64 decode SAML message");
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoder.java
index c5832294b..83e5c1bbd 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoder.java
@@ -117,6 +117,7 @@ public class HTTPRedirectDeflateDecoder extends BaseSAMLHttpServletRequestDecode
         if (samlMessageEncoded != null) {
             try (final InputStream samlMessageIns = decodeMessage(samlMessageEncoded)) {
                 final SAMLObject samlMessage = (SAMLObject) unmarshallMessage(samlMessageIns);
+                SAMLBindingSupport.checkSAML2MessageType("SAMLRequest".equals(samlMessageParamName), samlMessage);
                 messageContext.setMessage(samlMessage);
                 log.debug("Decoded SAML message");
             } catch (final IOException e) {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLBindingSupportXMLObjectTests.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLBindingSupportXMLObjectTests.java
new file mode 100644
index 000000000..f781f34d7
--- /dev/null
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLBindingSupportXMLObjectTests.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed 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.opensaml.saml.common.binding.impl;
+
+import org.opensaml.core.testing.XMLObjectBaseTestCase;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.messaging.decoder.MessageDecodingException;
+import org.opensaml.saml.common.binding.SAMLBindingSupport;
+import org.opensaml.saml.saml1.core.Request;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.Response;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+ at SuppressWarnings("javadoc")
+public class SAMLBindingSupportXMLObjectTests extends XMLObjectBaseTestCase {
+    
+    @Test
+    public void checkSAML1MessageType()  {
+        final Request request = (Request) XMLObjectSupport.buildXMLObject(Request.DEFAULT_ELEMENT_NAME);
+        final org.opensaml.saml.saml1.core.Response response =
+                (org.opensaml.saml.saml1.core.Response) XMLObjectSupport.buildXMLObject(
+                        org.opensaml.saml.saml1.core.Response.DEFAULT_ELEMENT_NAME);
+        
+        // Success cases
+        try {
+            SAMLBindingSupport.checkSAML1MessageType(true, request);
+        } catch (final MessageDecodingException e) {
+            Assert.fail("Message was Response and a response was expected", e);
+        }
+        try {
+            SAMLBindingSupport.checkSAML1MessageType(false, response);
+        } catch (final MessageDecodingException e) {
+            Assert.fail("Message was Response and a response was expected", e);
+        }
+        
+        // Failure cases
+        try {
+            SAMLBindingSupport.checkSAML1MessageType(true, response);
+            Assert.fail("Message was Response and a request was expected");
+        } catch (final MessageDecodingException e) {
+            // this is the valid result
+        }
+        try {
+            SAMLBindingSupport.checkSAML1MessageType(false, request);
+            Assert.fail("Message was AuthnRequest and a response was expected");
+        } catch (final MessageDecodingException e) {
+            // this is the valid result
+        }
+    }
+
+    @Test
+    public void checkSAML2MessageType()  {
+        final AuthnRequest authnRequest = (AuthnRequest) XMLObjectSupport.buildXMLObject(AuthnRequest.DEFAULT_ELEMENT_NAME);
+        final Response response = (Response) XMLObjectSupport.buildXMLObject(Response.DEFAULT_ELEMENT_NAME);
+        
+        // Success cases
+        try {
+            SAMLBindingSupport.checkSAML2MessageType(true, authnRequest);
+        } catch (final MessageDecodingException e) {
+            Assert.fail("Message was Response and a response was expected", e);
+        }
+        try {
+            SAMLBindingSupport.checkSAML2MessageType(false, response);
+        } catch (final MessageDecodingException e) {
+            Assert.fail("Message was Response and a response was expected", e);
+        }
+        
+        // Failure cases
+        try {
+            SAMLBindingSupport.checkSAML2MessageType(true, response);
+            Assert.fail("Message was Response and a request was expected");
+        } catch (final MessageDecodingException e) {
+            // this is the valid result
+        }
+        try {
+            SAMLBindingSupport.checkSAML2MessageType(false, authnRequest);
+            Assert.fail("Message was AuthnRequest and a response was expected");
+        } catch (final MessageDecodingException e) {
+            // this is the valid result
+        }
+    }
+
+}
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoderTest.java
index a09d15e75..f1fde8cbe 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml1/binding/decoding/impl/HTTPPostDecoderTest.java
@@ -20,10 +20,12 @@ import java.net.URL;
 import javax.annotation.Nonnull;
 
 import org.opensaml.core.testing.XMLObjectBaseTestCase;
+import org.opensaml.core.xml.util.XMLObjectSupport;
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.decoder.MessageDecodingException;
 import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.common.binding.SAMLBindingSupport;
+import org.opensaml.saml.saml1.core.Request;
 import org.opensaml.saml.saml1.core.Response;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.testng.Assert;
@@ -86,6 +88,23 @@ public class HTTPPostDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertEquals(SAMLBindingSupport.getRelayState(messageContext), expectedRelayValue);
     }
     
+    /**
+     * Test decoding message when the SAMLResponse param incorrectly holds a non-response message.
+     * 
+     * @throws Exception if something goes wrong
+     */
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLResponseParamHoldsRequest() throws Exception {
+        final Request samlRequest = (Request) XMLObjectSupport.buildXMLObject(Request.DEFAULT_ELEMENT_NAME);
+        assert samlRequest != null;
+
+        httpRequest.setParameter("SAMLResponse", encodeMessage(samlRequest));
+
+        populateRequestURL(httpRequest, "https://sp.example.org/sso/acs");
+
+        decoder.decode();
+    }
+    
     /**
      * Test decoding a base64 invalid message. Should throw a {@link MessageDecodingException}
      * wrapping a DecodingException.
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoderTest.java
index a43adf483..d338a8a8d 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostDecoderTest.java
@@ -72,6 +72,22 @@ public class HTTPPostDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertTrue(messageContext.getMessage() instanceof RequestAbstractType);
         Assert.assertEquals(SAMLBindingSupport.getRelayState(messageContext), expectedRelayValue);
     }
+
+    /**
+     * Test decoding a SAML Response message incorrectly supplied in a "SAMLRequest" param.
+     * 
+     * @throws MessageDecodingException ...
+     */
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLRequestParamHoldsResponse() throws MessageDecodingException {
+        httpRequest.setParameter("SAMLRequest", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWxwOlJlc3Bvbn"
+                + "NlIElEPSJmb28iIElzc3VlSW5zdGFudD0iMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnN"
+                + "hbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPjxzYW1scDpTdGF0dXM+PHNhbWxwOlN0YXR1c0Nv"
+                + "ZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbHA6U3RhdHVzPjwvc"
+                + "2FtbHA6UmVzcG9uc2U+");
+        
+        decoder.decode();
+    }
     
     /**
      * Test decoding a Base64 invalid SAML Request. Should throw a {@link MessageDecodingException} wrapping
@@ -112,4 +128,18 @@ public class HTTPPostDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertEquals(SAMLBindingSupport.getRelayState(messageContext), expectedRelayValue);
     }
     
+    /**
+     * Test decoding a SAML request message incorrectly supplied in a "SAMLResponse" param.
+     * 
+     * @throws MessageDecodingException ...
+     */
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLResponseParamHoldsRequest() throws MessageDecodingException {
+        httpRequest.setParameter("SAMLResponse", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWxwOkF1dGhuUm"
+                + "VxdWVzdCBJRD0iZm9vIiBJc3N1ZUluc3RhbnQ9IjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwWiIgVmVyc2lvbj0iMi4wIiB4bW"
+                + "xuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIi8+");
+
+        decoder.decode();
+    }
+    
 }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostSimpleSignDecoderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostSimpleSignDecoderTest.java
index 8aee74284..9c0240037 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostSimpleSignDecoderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPPostSimpleSignDecoderTest.java
@@ -78,6 +78,21 @@ public class HTTPPostSimpleSignDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertNull(messageContext.ensureSubcontext(SimpleSignatureContext.class).getSignedContent());
     }
     
+    /**
+     * Test decoding a SAML Response message incorrectly supplied in a "SAMLRequest" param.
+     * 
+     * @throws MessageDecodingException ...
+     */
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLRequestParamHoldsResponse() throws MessageDecodingException {
+        httpRequest.setParameter("SAMLRequest", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWxwOlJlc3Bvbn"
+                + "NlIElEPSJmb28iIElzc3VlSW5zdGFudD0iMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnN"
+                + "hbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPjxzYW1scDpTdGF0dXM+PHNhbWxwOlN0YXR1c0Nv"
+                + "ZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbHA6U3RhdHVzPjwvc"
+                + "2FtbHA6UmVzcG9uc2U+");
+        
+        decoder.decode();
+    }
  
     /**
      * Test decoding a SAML httpRequest.
@@ -157,4 +172,18 @@ public class HTTPPostSimpleSignDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertNull(messageContext.ensureSubcontext(SimpleSignatureContext.class).getSignedContent());
     }
     
+    /**
+     * Test decoding a SAML request message incorrectly supplied in a "SAMLResponse" param.
+     * 
+     * @throws MessageDecodingException ...
+     */
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLResponseParamHoldsRequest() throws MessageDecodingException {
+        httpRequest.setParameter("SAMLResponse", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHNhbWxwOkF1dGhuUm"
+                + "VxdWVzdCBJRD0iZm9vIiBJc3N1ZUluc3RhbnQ9IjE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwWiIgVmVyc2lvbj0iMi4wIiB4bW"
+                + "xuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIi8+");
+
+        decoder.decode();
+    }
+    
 }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoderTest.java
index b02fbbc63..f67dce9bc 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/binding/decoding/impl/HTTPRedirectDeflateDecoderTest.java
@@ -90,7 +90,7 @@ public class HTTPRedirectDeflateDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertEquals(SAMLBindingSupport.getRelayState(messageContext), expectedRelayValue);
         Assert.assertNull(messageContext.ensureSubcontext(SimpleSignatureContext.class).getSignedContent());
     }    
-   
+    
     @Test
     public void testRequestDecoding() throws MessageDecodingException, MessageEncodingException, 
                                                             MarshallingException, EncodingException {
@@ -110,6 +110,32 @@ public class HTTPRedirectDeflateDecoderTest extends XMLObjectBaseTestCase {
         Assert.assertNull(messageContext.ensureSubcontext(SimpleSignatureContext.class).getSignedContent());
     }
     
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLRequestParamHoldsResponse() throws MessageDecodingException {
+        // Note, Spring's Mock objects don't do URL encoding/decoding, so this is the URL decoded form
+        httpRequest
+                .setParameter(
+                        "SAMLRequest",
+                        "fZAxa8NADIX3/opDe3yXLG2F7VASCoF2qdMM3Y6LkhrOp8PSlfz8uqYdvBTeIMHT08ert7chmi8apefUwLpyYCgFPvfp2sD78Xn1ANv2rhY/xIxvJJmTkNmTaJ+8zkefqhmtpZsfcqSKxyuYw76BC/M0iBQ6JFGfdMp/vHcrt550dA5nVc65DzCnP4TND8IElQTnpw2UMSF76QWTH0hQA3ZPry84OTGPrBw4QvuL2KnXIsttx2cyJx8L/R8msxu7EgKJgG1ruwy1yxrabw==");
+
+        populateRequestURL(httpRequest, "http://example.org");
+
+        decoder.decode();
+    }    
+    
+    @Test(expectedExceptions = MessageDecodingException.class)
+    public void testSAMLResponseParamHoldsRequest() throws MessageDecodingException, MessageEncodingException, 
+                                                            MarshallingException, EncodingException {
+        final AuthnRequest samlRequest =
+                (AuthnRequest) unmarshallElement("/org/opensaml/saml/saml2/binding/AuthnRequest.xml");
+        assert samlRequest != null;
+        samlRequest.setDestination(null);
+
+        httpRequest.setParameter("SAMLResponse", encodeMessage(samlRequest));
+
+        decoder.decode();
+    }
+   
     @Test
     public void testRequestDecodingWithSignature() throws MessageDecodingException, MessageEncodingException, 
                                                             MarshallingException, EncodingException, UnsupportedEncodingException {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list