vidyuthd / owasp-esapi-java

Automatically exported from code.google.com/p/owasp-esapi-java
0 stars 0 forks source link

login() should not require POST method if user is found in session #189

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

1. Use the Cross Site Reference Forgery lab solution from the ESAPI SwingSet 
1.0 release (http://code.google.com/p/swingset-demo/).  The solution URL is 
https://localhost:8443/SwingSet/main?function=CSRF&solution, which forwards to 
CSRFSolution.jsp.  CSRFSolution.jsp uses a form to authenticate the user from 
an HTML form to populate the ESAPI current user.
2. After the user has logged in, they can use the Transfer Funds link 
(https://localhost:8443/SwingSet/main?function=TransferFunds&solution&ctoken=...
) to access TransferFundsSolution.jsp, which validates that the CSRF token 
inserted by CSRFSolution.jsp matches the token associated with the current 
ESAPI user.
3. The SwingSet TransferFundsSolution.jsp uses 
ESAPI.authenticator.getCurrentUser() to retrieve the current user.  This should 
only succeed if the same thread processes both JSP requests.  Since this will 
not be true for most web containers, I modified the JSP to use the no-argument 
version of ESAPI.authenticator.login() instead to retrieve the ESAPI current 
user.

What is the expected output? What do you see instead?

Using login() to populate the ESAPI current user should guarantee that the CSRF 
tokens will match once a user has successfully logged in.  
TransferFundsSolution.jsp should successfully load, and the scripted logic on 
the page should indicate that the CSRF token was validated.

Instead, using ESAPI.authenticator.login() in  TransferFundsSolution.jsp causes 
an AccessControlException to be thrown during the processing of 
TransferFundsSolution.jsp.  The SwingSet Controller servlet catches this error 
and silently redirects to the application index.jsp.

What version of the product are you using? On what operating system?

ESAPI 2.0RC10 (built from 
http://owasp-esapi-java.googlecode.com/svn/tags/releases/2.0_rc10)
Sun Java version 1.5.0_21
Windows XP Professional Version 2002 SP3
Tomcat 5.5.26

Does this issue affect only a specified browser or set of browsers?

The behavior appears to reproduce consistently in IE 7.0.5730.11, Firefox 
3.6.12, and Google Chrome 7.0.517.44.

Please provide any additional information below.

AbstractAuthenticator.login(HttpServletRequest, HttpServletResponse) first 
attempts to locate the ESAPI current user in the HttpSession (i.e. 
getUserFromSession()).  This call succeeds, setting the local variable user to 
the object retrieved from HttpSession.

After the host address is updated on the user object, login() calls 
ESAPI.httpUtilities().assertSecureRequest().  Assuming the default 
implementation in DefaultHTTPUtilities, this does two things: 1) assert that 
the protocol used in the request was HTTPS 2) assert that the method used by 
the request was POST.  Since login() was called from a JSP that was invoked 
through a simple link traversal, the second assertion fails, and login() throws 
AccessControlException.  A stack trace containing a failing run is attached.

It appears that requiring all calls to login() to use method POST may be too 
restrictive, and that this validation should only be performed when the HTTP 
request is being used as the source of authentication information (i.e. when 
loginWithUsernameAndPassword() is called).

As a possibly unrelated observation, 
ESAPI.httpUtilities().assertSecureRequest() is being passed 
ESAPI.currentRequest(), rather than a reference to the HttpServletRequest 
object ("request") in the login() signature.  In many cases, both of these will 
reference the same object, but in the case where login() is explicitly called 
with HttpServletRequest and HttpServletResponse objects. it seems like this may 
promote counterintuitive behavior.

Original issue reported on code.google.com by kevin.c...@scynexis.com on 6 Dec 2010 at 6:05

Attachments: