Sarath Upadrista Sarath Upadrista - 1 year ago 166
HTML Question

How to prevent XSS for the form action URL?

We use Shibboleth's SingleSingOut(SSO) to do the authentication.Shibboleth is an open-source project which has been integrated into our project. Shibboleth will do the redirect to login.jsp page, if the user has not been authenticated.Now we have customized login.jsp page to support localization. So, the form actionUrl has to be sent by the Shibboleth IDP(Identity Provider) to perform the authentication. Here is the below sample code which the Shibboleth has provided:

<% if(request.getAttribute("actionUrl") != null){ %>
<form id="login" action="<%=request.getAttribute("actionUrl")%>" method="post">
<% }else{ %>
<form id="login" action="j_security_check" method="post">
<% } %>

<% if ("true".equals(request.getAttribute("loginFailed"))) { %>
<p class="form-element form-error">Login has failed. Double-check your username and password.</p>
<% } %>

Log in to <idpui:serviceName/>

<label for="username">Username</label>
<input class="form-element form-field" name="j_username" type="text" value="">

<label for="password">Password</label>
<input class="form-element form-field" name="j_password" type="password" value="">

<button class="form-element form-button" type="submit">Login</button>

Now I have used the OWASP ZAP tool to check the security attack. It has raised a High Risk at the below code

<form id="login" action="<%=request.getAttribute("actionUrl")%>" method="post">

It has told that there can be XSS (Cross-site Scripting) attack so, it has asked me to encode the above code.

How can I prevent the XSS(Cross Site Scripting) for the form action url. Because, it is an untrusted data is there any way to encode the URL. After some research I found that, its better to use ESAPI.encoder().encodeForURL('url'); method. My doubt is that, is it a correct way to use the ESAPI.encoder().encodeForURL('url') for the form action URL?

From the Cross_Site_Scripting Prevention Cheat sheet

Actual form action url:

<form name="loginForm" id="login" method="POST" action="<%=request.getParameter("actionUrl")%>">

Encoded form action url:

<form name="loginForm" id="login" method="POST" action="<%=ESAPI.encoder().encodeForURL(request.getParameter("actionUrl"))%>">

Any suggestions would be appreciated.

fgb fgb
Answer Source

ESAPI.encoder().encodeForURL() is not correct because this does percent encoding of the whole string which can corrupt the url. It's meant more for encoding individual parameters within a url.

In this context, within an attribute, ESAPI.encoder().encodeForHTMLAttribute() should be used.

There is an extra problem here though. If the url is not trusted, then the user could be sending their log in details to an untrusted site. You should check exactly where the url comes from and make sure the user can't control its contents.

If the url is always of a similar format, then you can check against this in the controller.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download