<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
span.apple-style-span
        {mso-style-name:apple-style-span;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Consolas","serif";
        color:black;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body bgcolor=white lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I’ve always thought that the *<b>correct</b>* way to handle these nested encoding contexts is to use multiple encoding schemes – carefully!!  But I haven’t done extensive testing necessary to figure out exactly how to deal with all the possible nested encoding contexts.<o:p></o:p></span></p><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>--Jeff<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p></div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif";color:windowtext'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif";color:windowtext'> esapi-user-bounces@lists.owasp.org [mailto:esapi-user-bounces@lists.owasp.org] <b>On Behalf Of </b>Chris Schmidt<br><b>Sent:</b> Monday, June 20, 2011 4:27 PM<br><b>To:</b> esapi-user@lists.owasp.org<br><b>Subject:</b> Re: [Esapi-user] Tricky encoding question<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>Couple of things - always use the context that most closely matches where you are outputting the data - in this case, the data is a URL and thus url encoding should be used. However, as you mentioned, the data is in a javascript parameter (jsdata) context, so ideally you would want to ensure that there are no unescaped javascript terminators in your output as well. Without writing some test cases, I am not 100% sure - but I imagine that URL encoding along would also encode the relevant javascript terminators &quot;, ' which would eliminate the possibility of the user being able to break context from the javascript parameter string. <br><br>That being said, and moving on to your point of &quot;blah&amp;a=b&quot; - this should absolutely be verboten as it opens up a slew of parameter injection and override possibilities for an attacker to play with. <br><br><br><br>On 6/20/2011 8:33 AM, Matthew Presson wrote: <o:p></o:p></p><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>I have come across a scenario in an application and would like some advice on the subject of applying the proper encoding. &nbsp;<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Scenario:<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>A developer is taking user input and using it to dynamically construct an URL which is used in an onClick event handler of an &lt;a&gt; tag. &nbsp;The code (JSP) looks similar to this:<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&lt;a HREF=&quot;&quot;<br>onClick=&quot;window.open('<a href="http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=" target="_blank"><span style='color:#1C51A8'>http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=</span></a>&lt;%=request.getParameter(&quot;test&quot;)%&gt;', 'windowRef', '</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>resizable=yes,scrollbars=yes,status=no,location=no,toolbars=yes,height=500,width=800'); return false;&quot;&gt;link text&lt;/a&gt;</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>As you can see, param3 is vulnerable to XSS. &nbsp;The tricky part is that the data is being used to form a URL (URL Context) but from within a JavaScript event handler (JavaScript Context).&nbsp;<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><p class=MsoNormal><span class=apple-style-span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>The question is - Which of the following encoding strategies would be the right one to use? </span><o:p></o:p></span></p><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Option 1: Only use URL encoding<o:p></o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&lt;a HREF=&quot;&quot;<br>onClick=&quot;window.open('<a href="http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=" target="_blank"><span style='color:#1C51A8'>http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=</span></a>&lt;%= OutputEncoder.encodeForURL(request.getParameter(&quot;test&quot;)) %&gt;', 'windowRef', '</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>resizable=yes,scrollbars=yes,status=no,location=no,toolbars=yes,height=500,width=800'); return false;&quot;&gt;link text&lt;/a&gt;</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>This option appears to work well, but are still in a JavaScript context and are unsure if there would still be attack strings that would allow for a successful XSS attack.<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Option 2: Only use JavaScript encoding:<o:p></o:p></span></p></div><div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&lt;a HREF=&quot;&quot;<br>onClick=&quot;window.open('<a href="http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=" target="_blank"><span style='color:#1C51A8'>http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=</span></a>&lt;%= OutputEncoder.encodeForJavaScript(request.getParameter(&quot;test&quot;)) %&gt;', 'windowRef', '<br>resizable=yes,scrollbars=yes,status=no,location=no,toolbars=yes,height=500,width=800'); return false;&quot;&gt;link text&lt;/a&gt;</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></blockquote></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>This option works from a security standpoint, but breaks in scenarios where the value of the parameter&nbsp;<i>test</i>&nbsp;is supposed to equal &quot;blah&amp;a=b&quot;. &nbsp;When using only JavaScript encoding, page.jsp would read the value of param3 as blah and have an extra parameter named a with the value b instead of having the value of param3 equal blah&amp;a=b which ultimately results in a functional defect.<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Option 3: Double encode using URL AND JavaScript encoding<o:p></o:p></span></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&lt;a HREF=&quot;&quot;<br>onClick=&quot;window.open('<a href="http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=" target="_blank"><span style='color:#1C51A8'>http://www.example.com/app/page.jsp?param1=a&amp;param2=b&amp;param3=</span></a>&lt;%= OutputEncoder.encodeForJavaScript(OutputEncoder.encodeForURL(request.getParameter(&quot;test&quot;))) %&gt;', 'windowRef', '<br>resizable=yes,scrollbars=yes,status=no,location=no,toolbars=yes,height=500,width=800'); return false;&quot;&gt;link text&lt;/a&gt;</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p></blockquote><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>This seems to also work, but am not sure about recommending a double-encoding strategy. &nbsp;For one, it adds another level of complexity that could potentially lead to problems down the road. &nbsp;Secondly, isn't double-encoding usually frowned upon as a solution?&nbsp;<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Please let me know if any of this does not make sense, or if I can provide you with any additional information.<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p>&nbsp;</o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Thanks,&nbsp;<br>Matt<o:p></o:p></span></p></div><pre><o:p>&nbsp;</o:p></pre><pre><o:p>&nbsp;</o:p></pre><pre>_______________________________________________<o:p></o:p></pre><pre>Esapi-user mailing list<o:p></o:p></pre><pre><a href="mailto:Esapi-user@lists.owasp.org">Esapi-user@lists.owasp.org</a><o:p></o:p></pre><pre><a href="https://lists.owasp.org/mailman/listinfo/esapi-user">https://lists.owasp.org/mailman/listinfo/esapi-user</a><o:p></o:p></pre><p class=MsoNormal><o:p>&nbsp;</o:p></p></div></body></html>