[Esapi-user] encodeForHTMLAttribute the value of an <input>

Rod Widdowson rdw at steadingsoftware.com
Fri Mar 23 13:44:11 UTC 2012


For the record - I misdiagnosed:

 

Olivier,

 

Thank you very much.  This gave me exactly the information I needed to proceed.  My problem was that the method I was using to print
the form was already applying some encoding for me.

 

So when I bracketed that with the ESAPI code I was encoding an already encoded string, hence I saw an '&' turning into an '&'.
I guess if I walked away from the problem  I would have worked that out in a week or two...

 

The bottom line is that my sanity is restored and my faith in the XSS prevention guide is renewed and increased.  And I learn yet
again the important of understand precisely what help my helper libraries are providing..

 

Thank again and apologies  for the noise.

 

/Rod

 

 

From: Olivier Jaquemet [mailto:olivier.jaquemet at jalios.com] 
Sent: 23 March 2012 11:36
To: Rod Widdowson
Cc: esapi-user at lists.owasp.org
Subject: Re: [Esapi-user] encodeForHTMLAttribute the value of an <input>

 

Hi Rod.

If I correctly understood your problem (which might not be the case), I think you are mixing several things : 

1.  the value that you are going to write in the HTML. Whatever the context. This value will be read and interpreted by the browser,
and thus need to be encoded using appropriate method depending on its location (attribute, url, html).

2. the value which is send in an HTTP request 
* when submiting a form (post or get) : in this case the value is extracted and decoded by the browser from the input's value and
will be sent in an appriopriate encoding for decoding by the appserver and then recevied by your bean in its clear text form -> each
input/textarea value must have been encoded using encodeForHTMLAttribute/encodeForHTML
* when clicking on a link (a href), using a GET : in this case the value is extracted and decoded by the browser from the href
values -> each parameter value must have been encode using encodeForURL
* when typed manually in your browser's location, in such case, you must use URL encoded value. You cannot use the value returned by
encodeForHTMLAttribute since this value is targetted at the HTML and must be interpreted first by the browser
-> each parameter value must use URL encoding scheme

To sum up using an example value "Father&Son" (which will always be received in this form by the server) : 

1. use URL encoded value when typing url in browser's location : 
/action?foo=bar&company=Father%26Son

2. encode value : 
* using encodeForHTMLAttribute in input's value : 
<input type="text" name="company" value="Father&Son" />

* using encodeForHTML in textarea 
<textarea name="company">Father&Son</textarea>

* using encodeForURL in each parameter of a href link
<a href="/action?company=Father%26Son">Click Me</a>

3. Do not decode anything, this is handled by browser/appserver 

4. If possible, validate the parameters received on server side against a whitelist

Did it help ?

Olivier

On 23/03/2012 11:29, Rod Widdowson wrote: 

This seems so obvious a question that I spent some time searching the archives.  My apologies if this has been touched and I missed
it - pointer to the solution is a great answer.
 
One of the stages of a web application I maintain has the simple task of constructing a form based on user's input and several other
parameters passed in (from a form or pseudo form on the previous stage).
 
That is to say when approached as:
 
https://host/app/page1?return=returnValue
 
I need to redirect to:
 
https://host/app/page2?return=returnValue <https://host/app/page2?return=returnValue&param=param> &param=param
 
returnValue is URLEncoded on 'input' and that encoding has to be preserved on 'output'
 
So the pseudo HTML for my constructed web pages looks like this: (I'm using JSP but the principal is the constant)
 
<form>
  <input type="hidden" name="return" value="<bean:write name="returnParam" />" />
  <select name="param">
    <option> [...]
 
So far so good.  But since returnValue is (for the sake of this question) untrusted we need to harden this using RULE2 in the XSS
cheat sheet:
 
  <input type="hidden" name="return" value="<esapi:encodeForHTMLAttribute><bean:write name="returnValue"
/><e/sapi:encodeForHTMLAttribute>" />
 
Or do we, because this is where the wheels begin to fall off.
 
The trouble is that returnValue is in the form of a URL = which we will eventually dispatch to (after significant policing against a
white list I should say).  To make things exciting that URL is garnished with a parameter - for instance the URL (*after* decoding)
might be https://site.com/Shibboleth.sso/initiator?SAMLDS=1
<https://site.com/Shibboleth.sso/initiator?SAMLDS=1&target=cookie%3A6eafc6f2> &target=cookie%3A6eafc6f2) 
 
So I am given
 
https://host/app/page1?https%3A%2F%2Fsite.com%2FShibboleth.sso%2initiator%3FSAMLDS%3D1%26target%3Dcookie%253A6eafc6f2
<https://host/app/page1?https%3A%2F%2Fsite.com%2FShibboleth.sso%252initiator%3FSAMLDS%3D1%26target%3Dcookie%253A6eafc6f2> 
 
And I need to produce 
 
https://host/app/page2?https%3A%2F%2Fsite.com%2FShibboleth.sso%2initiator%3FSAMLDS%3D1%26target%3Dcookie%253A6eafc6f2
<https://host/app/page2?https%3A%2F%2Fsite.com%2FShibboleth.sso%252initiator%3FSAMLDS%3D1%26target%3Dcookie%253A6eafc6f2&param=param
> &param=param
 
Because of form encoding I therefore have to create the pseudo-html
 
<form>
  <input type="hidden" name="return" value= <https://site.com/Shibboleth.sso/initiator?SAMLDS=1&target=cookie%3A6eafc6f2>
"https://site.com/Shibboleth.sso/initiator?SAMLDS=1&target=cookie%3A6eafc6f2" />
  <select name="param">
    <option>
[...]
 
But the trouble here is that pesky '&' - if I feed that string into encodeForHTMLAttribute the '&' is going to be rendered as
'&' which will then cause brokenness downstream.
 
I can construct numerous arguments as to why it's OK, for instance "it is going to be policed afterwards"; but just dropping that
encoding flies too closely in the face of RULE2 to be acceptable to me off hand and I am not prepared to accept "well it works like
that and it doesn't if I escape", that is the sound of doom to me.
 
So I'm coming to the experts here:
 - Are attributes to <input/> somehow special (because of forms encoding)?
 - I read somewhere in this list that encoding can destroy data.  Is this one such case?  
 - Is another alternative to make the data "trusted" (and hence remove the need to encode by RULE2).  How do I do that, absent
encoding it (which we see doesn't work)?
 
It actually turns out that I do the white list testing prior to generating the webpage (as well as afterwards) - would this be
sufficient?  
 
I apologise for the obvious question, but I am extremely careful where this stuff is concerned.  Because I do not do this every day
I need to spend a lot of time making sure I understand the principals, it makes my brain bend and I am never going to be confident
enough to call myself an expert and make a call like this.  But the readership of this list is expert.
 
Thanks in advance
 
Rod Widdowson
 
 
 
 
_______________________________________________
Esapi-user mailing list
Esapi-user at lists.owasp.org
https://lists.owasp.org/mailman/listinfo/esapi-user
 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.owasp.org/pipermail/esapi-user/attachments/20120323/06e70248/attachment.html>


More information about the Esapi-user mailing list