when a form is submited that inserts a record into the database and the operation was successful, I do a redirect and then pass some parameters in the Url to display the newly inserted record along with a header message (i.e., "Insert was successful").
response.sendRedirect(yPage + "?pid=" + ipd + "&feedback=" + form.getFormFeebackSB() );
I would then display in jsp like:
<c:out value="${param.feedback}" />
I use a redirect instead of a forward because I want the operation to be idempotent. When I used forward
users who hit refresh after a successful insert most often always clicked retry on the warning popup and it resulted in duplicate inserts.
Our IT department then discovered that I had a XSS vulnerability:
page.jsp?feedback=%3Cscript%20type=%22text/javascript%22%3Ealert%28%27xss%27%29;%3C/script%3E
So I changed to this:
<c:out value="${param.feedback}" escapeXml='true'/>
but now any <br>
in my FeedbackSB get escaped and I end up with a header message as such
Insert was successful<br>An email was sent to Joe<br>Now Complete the XYZ Form;
what is the standard way to pass messages back to user, while keeping any submits idempotent and protecting against XSS?
I searched Flash Scope and came across this http://blog.smartkey.co.uk/2011/01/implementing-flash-scope-in-java-web-applications/ Since my application would require a lot of work to incorporate a framework, the filter mentioned in that link was easy to incorporate and was able to implement flash scope with very little effort.
Don't pass the message itself in a redirect. Store the message under a unique key in the session, redirect with the key of this message as URL parameter, then go to the session, get the message, and display it.
I would also remove the message from the session immediately: if the user refreshes, there is no reason to tell him again that the insert was successful.
Most of the MVC frameworks do that for you, using what they usually call a Flash scope (session attributes that are removed from the session as soon as they've been retrieved).