<font size=2 face="sans-serif">Thanks, Jeff.  Why is it that the
sessions look so much alike -- same session ID and context values?  That
surprised me.</font>
<br><font size=2 face="sans-serif"><br>
Chris<br>
<br>
IBM Tivoli Systems<br>
Research Triangle Park, NC<br>
(919) 224-2240<br>
Internet:  barlock@us.ibm.com</font>
<br>
<br>
<br>
<br><font size=1 color=#5f5f5f face="sans-serif">From:      
 </font><font size=1 face="sans-serif">Jeff Williams <jeff.williams@aspectsecurity.com></font>
<br><font size=1 color=#5f5f5f face="sans-serif">To:      
 </font><font size=1 face="sans-serif">Chris Barlock/Raleigh/IBM@IBMUS,
"esapi-user@lists.owasp.org" <esapi-user@lists.owasp.org>,
</font>
<br><font size=1 color=#5f5f5f face="sans-serif">Date:      
 </font><font size=1 face="sans-serif">04/03/2013 06:50 PM</font>
<br><font size=1 color=#5f5f5f face="sans-serif">Subject:    
   </font><font size=1 face="sans-serif">RE: [Esapi-user]
Attempt to Fix a CSRF</font>
<br>
<hr noshade>
<br>
<br>
<br><font size=2 color=#004080 face="Calibri">JavaEE Sessions aren’t shared
across WAR files.  If you’re using Servlet 3.0 you might try something
like this in web.xml…</font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri"><session-config></font>
<br><font size=2 color=#004080 face="Calibri">    <cookie-config></font>
<br><font size=2 color=#004080 face="Calibri">       
<path>/</path></font>
<br><font size=2 color=#004080 face="Calibri">    </cookie-config></font>
<br><font size=2 color=#004080 face="Calibri"></session-config></font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri">I’m pretty sure that this
will share the session cookie, but I haven’t tried this to verify that
the sessions are shared across contexts.  Let us know if you figure
out a workaround.</font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri">You might check out some
of the methods in HTTPUtilities that support CSRF tokens.  They might
make some of your code a tiny bit simpler.</font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri">Thanks,</font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri">--Jeff</font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 color=#004080 face="Calibri"> </font>
<br><font size=2 face="Tahoma"><b>From:</b> esapi-user-bounces@lists.owasp.org
[</font><a href="mailto:esapi-user-bounces@lists.owasp.org"><font size=2 face="Tahoma">mailto:esapi-user-bounces@lists.owasp.org</font></a><font size=2 face="Tahoma">]
<b>On Behalf Of </b>Chris Barlock<b><br>
Sent:</b> Wednesday, April 03, 2013 5:10 PM<b><br>
To:</b> esapi-user@lists.owasp.org<b><br>
Subject:</b> [Esapi-user] Attempt to Fix a CSRF</font>
<br><font size=3 face="Times New Roman"> </font>
<br><font size=2 face="Arial">I am attempting to fix a Cross-Site Request
Forgery using the technique that John Melton describes in the link on the
OWASP web site:</font><font size=3 face="Times New Roman"> <br>
</font><font size=3 color=blue face="Times New Roman"><u><br>
</u></font><a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29"><font size=2 color=blue face="Arial"><u>https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29</u></font></a><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
When we log in, add a token to the HTTP session object:</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 color=#a16252 face="Consolas"><br>
<%</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
String token = ESAPI.randomizer().getRandomString(8, EncoderConstants.<u>CHAR_ALPHANUMERICS</u>);</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
HttpSession reqSession = request.getSession();</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
reqSession.setAttribute(HTTPUtilities.CSRF_TOKEN_NAME, token);</font><font size=3 face="Times New Roman">
</font><font size=2 color=#a16252 face="Consolas"><br>
%></font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
When a page that needs to be protected is requested, get the token from
the session so that it is available to the form that will be POSTed back
to the server:</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 color=#4040c2 face="Consolas"><br>
<%-- Get the Cross-Site Request Forgery token. --%></font><font size=3 face="Times New Roman">
</font><font size=2 color=#a16252 face="Consolas"><br>
<%</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
HttpSession requestSession = request.getSession();</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
String csrfToken = (String) requestSession.getAttribute(HTTPUtilities.CSRF_TOKEN_NAME);</font><font size=3 face="Times New Roman">
</font><font size=2 color=#a16252 face="Consolas"><br>
%></font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
Include it in the form as a hidden input field.</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 color=#008080 face="Consolas"><br>
<</font><font size=2 color=#3f8080 face="Consolas">input</font><font size=2 face="Consolas">
</font><font size=2 color=#800080 face="Consolas">id</font><font size=2 face="Consolas">=</font><font size=2 color=#4200ff face="Consolas"><i>"csrfToken"</i></font><font size=2 face="Consolas">
</font><font size=2 color=#800080 face="Consolas">name</font><font size=2 face="Consolas">=</font><font size=2 color=#4200ff face="Consolas"><i>"</i></font><font size=2 color=#a16252 face="Consolas"><%=</font><font size=2 face="Consolas">HTTPUtilities.CSRF_TOKEN_NAME</font><font size=2 color=#a16252 face="Consolas">%></font><font size=2 color=#4200ff face="Consolas"><i>"</i></font><font size=2 face="Consolas">
<br>
    </font><font size=2 color=#800080 face="Consolas">type</font><font size=2 face="Consolas">=</font><font size=2 color=#4200ff face="Consolas"><i>"hidden"</i></font><font size=2 face="Consolas">
</font><font size=2 color=#800080 face="Consolas">value</font><font size=2 face="Consolas">=</font><font size=2 color=#4200ff face="Consolas"><i>"</i></font><font size=2 color=#a16252 face="Consolas"><%=</font><font size=2 face="Consolas">csrfToken</font><font size=2 color=#a16252 face="Consolas">%></font><font size=2 color=#4200ff face="Consolas"><i>"</i></font><font size=2 color=#008080 face="Consolas">/></font><font size=3 face="Times New Roman"><br>
</font><font size=2 face="Arial"><br>
When the form is processed, check that the two tokens match:</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 color=#4040c2 face="Consolas"><br>
    /**</font><font size=3 face="Times New Roman"> </font><font size=2 color=#4040c2 face="Consolas"><br>
     * Tests whether a Cross</font><font size=2 color=#8f8f8f face="Consolas">-</font><font size=2 color=#4040c2 face="Consolas">Site
Request Forgery is in progress by comparing a</font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     * token in the HTTP session object with one placed in the
form that is</font><font size=3 face="Times New Roman"> </font><font size=2 color=#4040c2 face="Consolas"><br>
     * being POSTed.</font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     * <br>
     * </font><font size=2 color=#71b2cf face="Consolas"><b>@param</b></font><font size=2 color=#4040c2 face="Consolas">
formParams</font><font size=3 face="Times New Roman"> </font><font size=2 color=#4040c2 face="Consolas"><br>
     *        The input fields of the form.</font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     * </font><font size=2 color=#71b2cf face="Consolas"><b>@param</b></font><font size=2 color=#4040c2 face="Consolas">
request</font><font size=3 face="Times New Roman"> </font><font size=2 color=#4040c2 face="Consolas"><br>
     *        The HTTP request.</font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     *        </font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     * </font><font size=2 color=#71b2cf face="Consolas"><b>@return</b></font><font size=2 color=#4040c2 face="Consolas">
</font><font size=2 color=#8f8f8f face="Consolas"><code></font><font size=2 color=#4040c2 face="Consolas">true</font><font size=2 color=#8f8f8f face="Consolas"></code></font><font size=2 color=#4040c2 face="Consolas">
if the tokens do not match and an attack is in</font><font size=3 face="Times New Roman">
</font><font size=2 color=#4040c2 face="Consolas"><br>
     *         progress; </font><font size=2 color=#8f8f8f face="Consolas"><code></font><font size=2 color=#4040c2 face="Consolas">false</font><font size=2 color=#8f8f8f face="Consolas"></code></font><font size=2 color=#4040c2 face="Consolas">
otherwise.</font><font size=3 face="Times New Roman"> </font><font size=2 color=#4040c2 face="Consolas"><br>
     */</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
        </font><font size=2 color=#820040 face="Consolas"><b>public</b></font><font size=2 face="Consolas">
</font><font size=2 color=#820040 face="Consolas"><b>static</b></font><font size=2 face="Consolas">
</font><font size=2 color=#820040 face="Consolas"><b>boolean</b></font><font size=2 face="Consolas">
isCSRFAttack(MultivaluedMap<String, String> formParams, HttpServletRequest
request) {</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
            </font><font size=2 color=#820040 face="Consolas"><b>boolean</b></font><font size=2 face="Consolas">
attack = </font><font size=2 color=#820040 face="Consolas"><b>false</b></font><font size=2 face="Consolas">;</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
            <br>
        HttpSession session = request.getSession();</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        String sessionCSRFToken = (String) session.getAttribute(HTTPUtilities.</font><font size=2 color=#0021bf face="Consolas"><i>CSRF_TOKEN_NAME</i></font><font size=2 face="Consolas">);</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        <br>
        String formCSRFToken = formParams.getFirst(HTTPUtilities.</font><font size=2 color=#0021bf face="Consolas"><i>CSRF_TOKEN_NAME</i></font><font size=2 face="Consolas">);</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        <br>
        </font><font size=2 color=#3f8080 face="Consolas">//
sessionCSRFToken should never be null, but just in case, no NPE...</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        </font><font size=2 color=#820040 face="Consolas"><b>if</b></font><font size=2 face="Consolas">
(sessionCSRFToken != </font><font size=2 color=#820040 face="Consolas"><b>null</b></font><font size=2 face="Consolas">
&& !sessionCSRFToken.equals(formCSRFToken)) {</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
            attack = </font><font size=2 color=#820040 face="Consolas"><b>true</b></font><font size=2 face="Consolas">;</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        }</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Consolas"><br>
        </font><font size=2 color=#3f8080 face="Consolas">//
Remove the CSRF token in the form, so it is not processed as a valid input
field.</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
        </font><font size=2 color=#820040 face="Consolas"><b>if</b></font><font size=2 face="Consolas">
(formCSRFToken != </font><font size=2 color=#820040 face="Consolas"><b>null</b></font><font size=2 face="Consolas">)
{</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
            formParams.remove(HTTPUtilities.</font><font size=2 color=#0021bf face="Consolas"><i>CSRF_TOKEN_NAME</i></font><font size=2 face="Consolas">);</font><font size=3 face="Times New Roman">
</font><font size=2 face="Consolas"><br>
        }</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Consolas"><br>
        </font><font size=2 color=#820040 face="Consolas"><b>return</b></font><font size=2 face="Consolas">
attack;</font><font size=3 face="Times New Roman"> </font><font size=2 face="Consolas"><br>
        }</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
The problem I have is that the page is requested from one WAR file and
the form is POSTed to a different WAR and the CSRF token is missing from
the HTTPSession object when the form is posted.  Here's the session
object when the GET occurs:</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
 {</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _iSession=# com.ibm.ws.session.store.memory.MemorySession #</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
 {</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _sessionId=twDANh7-Qj8Zj0i_aUpFj9n</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
hashCode : 321008117</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
create time : Wed Apr 03 16:48:21 EDT 2013</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
last access : Wed Apr 03 16:48:21 EDT 2013</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
max inactive interval : 1800</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
user name : user:customRealm/smadmin</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
valid session : true</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
new session : true</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
overflowed : false</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
app name : default_host/ccmDashboard</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
Attribute Names=[ctoken]</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _refCount=1</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 }</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
 </font><a href="mailto:_httpSessionContext=com.ibm.ws.session.http.HttpSessionContextImpl@cb67e2b"><font size=2 color=blue face="Arial"><u>_httpSessionContext=com.ibm.ws.session.http.HttpSessionContextImpl@cb67e2b</u></font></a><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
 }</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
and here is the one from the POST:</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
 {</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _iSession=# com.ibm.ws.session.store.memory.MemorySession #</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
 {</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _sessionId=twDANh7-Qj8Zj0i_aUpFj9n</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
hashCode : 2007005455</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
create time : Wed Apr 03 16:49:44 EDT 2013</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
last access : Wed Apr 03 16:49:44 EDT 2013</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
max inactive interval : 1800</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
user name : user:customRealm/smadmin</font><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
valid session : true</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
new session : true</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
overflowed : false</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
app name : default_host/ccm</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
Attribute Names=[]</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 _refCount=1</font><font size=3 face="Times New Roman"> </font><font size=2 face="Arial"><br>
 }</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
 </font><a href="mailto:_httpSessionContext=com.ibm.ws.session.http.HttpSessionContextImpl@cb67e2b"><font size=2 color=blue face="Arial"><u>_httpSessionContext=com.ibm.ws.session.http.HttpSessionContextImpl@cb67e2b</u></font></a><font size=3 face="Times New Roman">
</font><font size=2 face="Arial"><br>
 }</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
They are almost the same:  matchine sessionId and httpSessionContext
values -- but the timestamps, hashCodes and, most importantly, Attribute
Names array are different.  If the session objects really are different,
why do they share the same session ID and context values?  Any thoughts
on whether I'm doing this wrong or on how I might fix this?</font><font size=3 face="Times New Roman">
<br>
</font><font size=2 face="Arial"><br>
Thank you!</font><font size=3 face="Times New Roman"> <br>
</font><font size=2 face="Arial"><br>
Chris</font>
<br>