XSS mitigation with url encoded input

354 Views Asked by At

In one of my application to mitigate XSS attack I am using Encoder for html from OWASP but unfortunately it is not sufficient.

The pentesters have found a reflected cross site scripting threat where the input field content or the payload is URL encoded, the XSS encode/filter does not encode the data and allow the input to pass to the Javascript function.

The input is: %3Cscript%3Ealert%285%29%3C%2Fscript%3E or 39848%3balert(1)%2f%2f920

I have also tried Jsoup en html sanitize. They all are filtering the output/input only for html but this is already in a encoded form.

    function set() {
var span = window.parent.document.all.<%=Encode.forHtml(request.getParameter("address"))%>;
var action = '<%=Encode.forHtml(request.getParameter("action"))%>';

<logic:present name="postcodeForm" property="result">
<bean:size id="resultSize" name="postcodeForm" property="result"/>
<logic:notMatch name="resultSize" value="1">
span.innerHTML = "<bean:message key='error.result'/>";
span.className = "errSpec";

</logic:notMatch>
<logic:match name="resultSize" value="1">
<logic:iterate id="adres" name="postcodeForm" property="result">
span.innerHTML = "<bean:write name='address' property='Street'/>&nbsp;"
+ <%=Integer.parseInt(Encode.forHtml(searchString.substring(searchString.indexOf(',') + 1)))%>
<logic:present parameter="houseNumber">
<%=Encode.forHtml(request.getParameter("houseNumber"))%>
</logic:present>
+ "<br/>" + "<bean:write name='address' property='postcode'/>&nbsp;<bean:write name='address' property='houseNr'/>";
span.className = "";

if (action == 'postcode') {
var streetname= "<bean:write name='address' property='streetName' filter="false"/>";

Any idea or help is highly appreciated.

Thanks In Advance!

1

There are 1 best solutions below

0
Heiko Theißen On

Complexity is greatly decreased if all your request parameters are string values that occur in Javascript code. You need then only make sure that

  • any string delimiters that occur in a request parameter are properly escaped (" becomes \") and
  • the backslash is escaped (\ becomes \\) so that parameters cannot themselves contain escape sequences.

No HTML encoding is necessary for that.

You current code does not treat address as a string value, you should write window.parent.document.all["XXX"] instead of window.parent.document.all.XXX. This is produced with the following server-side code:

var span = window.parent.document.all["<%=
  request.getParameter("address")
   .replaceAll('"', '\\"')
   .replaceAll('\\', '\\\\')
%>"];
var action = "<%=
  request.getParameter("action")
   .replaceAll('"', '\\"')
   .replaceAll('\\', '\\\\')
%>";

Even if an attacker set address to the value "];alert(1), this would still be treated as a string:

var span = window.parent.document.all["\"];alert(1)"];

(I do not understand your current treatment of houseNumber, but this must also be handled as a string.)