Creating the SSO page of the SAML module

0
Hi team,   Within our app we need to improve security by changing our Content Security Policy. This will for example prevent injection attacks. This can be done per environment to set the HTTP headers. The current value we have for ‘script-src’ is “self unsafe-eval”. However, with these values in the script-src we can't execute the /SSO/ page anymore because it violates the Content Security Policy.  So for my question: where is the /sso/ page created? It has a onload function that is not allowed to execute. I want to re-write it so that it uses a function within a file, rather then from an inline source.  In our /login.html we redirect to the SSO page via a redirect like this: document.addEventListener("DOMContentLoaded", function () { window.open("/SSO/", "_self") });   The SSO page looks like this: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title> Single Sign On</title> <meta name="robots" content="noindex, nofollow"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1"> <meta name="apple-mobile-web-app-capable" content="yes"> <link rel="stylesheet" href="/styles/web/css/main.css"> <link rel="stylesheet" href="/css/login.css"> </head> <body onload="document.forms[0].submit()"> <noscript> <p> <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed. </p> </noscript> <form action="https&#x3a;&#x2f;&#x2f;acc.federatieveservice.nl&#x2f;aselectserver&#x2f;server&#x2f;saml20_sso" method="post"> <div> <input type="hidden" name="RelayState" value="OTHER AWESOME STUFF"/> <input type="hidden" name="SAMLRequest" value="SOME NICE STUFF"/> </div> <noscript> <div> <input type="submit" value="Continue"/> </div> </noscript> </form> </body> </html>   You can see in the body that is has the onload=”document.forms[0].submit()” function. This is what is not allowed anymore.  We are working with mendix 8.12.5 (not able to choose in tags) and a Mendix cloud server of version V4.   Thanks in advance, Martijn Rijneveen  
asked
2 answers
2

Assuming that you use the SAML module, the /SSO request handler is registered in SAMLRequestHandler.java and the "document.forms[0].submit()" part is included in the saml1-post-binding.vm Velocity template which is part of the same module.

I hope this answers your question.

answered
2

Hi folks, 

I sincerily hope none of you have to deal with my problem. However, if you need to change your CSP headers here is how to do it so that the SAML module has no inline-code.

 

In multiple Velocity templates this inline-code is used. In the templates:

  •  saml1-post-binding.vm
  • saml2-post-artifact-binding.vm
  • saml2-post-binding.vm
  • saml2-post-simplesign-binding.vm

 

These templates are located in [Mendixproject_Name]/resources/SAML/templates and all have the code:

 <body onload="document.forms[0].submit()">

To fix this we need to change the code in the .vm files to reference to the code in a JavaScript file within our app, instead of inline. 

So for example the saml1-post-binding.vm will look like this:

##
## Velocity Template for SAML 1 HTTP-POST binding
##
## Velocity context may contain the following properties
## action - String - the action URL for the form
## binding - String - the SAML binding type in use
## TARGET - String - the relay state for the message
## SAMLResponse - String - the Base64 encoded SAML Response

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

    <head>
    #parse ( "/templates/add-html-head-content.vm" )
	<script src="/scripts/submitLoginForm.js"></script>
    </head>

    <body>
        <noscript>
            <p>
                <strong>Note:</strong> Since your browser does not support JavaScript,
                you must press the Continue button once to proceed.
            </p>
        </noscript>
        
        <form action="${action}" method="post">
            <div>                
                #if($SAMLResponse)<input type="hidden" name="SAMLResponse" value="${SAMLResponse}"/>#end
                
                #if($TARGET)<input type="hidden" name="TARGET" value="${TARGET}"/>#end
                
            </div>
            <noscript>
                <div>
                    <input type="submit" value="Continue"/>
                </div>
            </noscript>
        </form>

        #parse ( "/templates/add-html-body-content.vm" )
        
    </body>
</html>

 Notice here that the <body> does not have the onload function anymore. Also in the <head> we have a <script> with a reference to “/scripts/submitLoginForm.js”. So the function is now replaced with a file that has the code.

To make the new .vm files work again we have to create a javascript file with the code to launch. We placed the JavaScript file in [Mendixproject_Name]/theme/scripts with the name ‘submitLoginForm.js’. The file has the following code:

window.onload = (event) => {
    document.forms[0].submit();
};

 

Now as a final step we had to add the javascript file in the CSP-header to make sure the browser allows it. To do that you need to go to the sprintr environment of you app. When you are there:

  1.  Go to environments >  details of environment (for example ACC and PROD) > Network
  2. In the HTTP header you can add your Content-security-policy
  3. Allow the javascript file in the ‘script-src’ by adding ‘{mendixapp_URL}/scripts/submitLoginForm.js’

 

If you might have any other questions about the CSP header, don't hesitate to ask. I'm also on the Mendix community Slack.

Go make it ;) 

 

 

 

answered