You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2001/08/16 05:52:09 UTC

cvs commit: jakarta-struts/src/share/org/apache/struts/action Action.java

craigmcc    01/08/15 20:52:09

  Modified:    src/share/org/apache/struts/action Action.java
  Log:
  Add a variation of the existing isTokenValid() method that optinally
  resets the token in the same, indivisible, operation.  This avoids a
  potential race condition that bypasses the check made by the transaction
  token, as follows:
  * User POSTs a form
  * Action finds the form valid and starts processing, without resetting
    the token at this point
  * User presses STOP and submits again
  * Action (on a second request thread) also finds the token valid
    (because the first thread didn't reset it).
  
  Note that, even if you call resetThread() immediately after
  isTokenValid(), there is still a (very small but finite) chance of a race
  condition with the old version.  To avoid that, you can do a "test and
  reset" atomically by calling:
  
    boolean ok = isTokenValid(request, true);
  
  Note that if you do this, you'll only be able to call isTokenValid() once,
  so save the result if you care about it.
  
  For backwards compatibility, calling isTokenValid(request) behaves as it
  did before, which is (in effect) the same as:
  
    isTokenValid(request, false);
  
  Many thanks to Yuhong Guo for explaining how this could happen, and
  suggesting a solution!
  
  Submitted by:	Yuhong Guo <YGuo@infinet-inc.com
  
  Revision  Changes    Path
  1.25      +46 -14    jakarta-struts/src/share/org/apache/struts/action/Action.java
  
  Index: Action.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Action.java	2001/07/19 02:11:52	1.24
  +++ Action.java	2001/08/16 03:52:09	1.25
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.24 2001/07/19 02:11:52 dwinterfeldt Exp $
  - * $Revision: 1.24 $
  - * $Date: 2001/07/19 02:11:52 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.25 2001/08/16 03:52:09 craigmcc Exp $
  + * $Revision: 1.25 $
  + * $Date: 2001/08/16 03:52:09 $
    *
    * ====================================================================
    *
  @@ -108,7 +108,7 @@
    * by this Action.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.24 $ $Date: 2001/07/19 02:11:52 $
  + * @version $Revision: 1.25 $ $Date: 2001/08/16 03:52:09 $
    */
   
   public class Action {
  @@ -434,21 +434,53 @@
        */
       protected boolean isTokenValid(HttpServletRequest request) {
   
  -        // Retrieve the saved transaction token from our session
  +        return (isTokenValid(request, false));
  +
  +    }
  +
  +
  +    /**
  +     * Return <code>true</code> if there is a transaction token stored in
  +     * the user's current session, and the value submitted as a request
  +     * parameter with this action matches it.  Returns <code>false</code>
  +     * <ul>
  +     * <li>No session associated with this request</li>
  +     * <li>No transaction token saved in the session</li>
  +     * <li>No transaction token included as a request parameter</li>
  +     * <li>The included transaction token value does not match the
  +     *     transaction token in the user's session</li>
  +     * </ul>
  +     *
  +     * @param request The servlet request we are processing
  +     * @param reset Should we reset the token after checking it?
  +     */
  +    protected boolean isTokenValid(HttpServletRequest request, boolean reset) {
  +
  +        // Retrieve the current session for this request
           HttpSession session = request.getSession(false);
           if (session == null)
               return (false);
  -        String saved = (String) session.getAttribute(TRANSACTION_TOKEN_KEY);
  -        if (saved == null)
  -            return (false);
   
  -        // Retrieve the transaction token included in this request
  -        String token = (String) request.getParameter(Constants.TOKEN_KEY);
  -        if (token == null)
  -            return (false);
  +        synchronized (session) {
   
  -        // Do the values match?
  -        return (saved.equals(token));
  +            // Retrieve the transaction token from this session, and
  +            // reset it if requested
  +            String saved = (String)
  +                session.getAttribute(TRANSACTION_TOKEN_KEY);
  +            if (saved == null)
  +                return (false);
  +            if (reset)
  +                session.removeAttribute(TRANSACTION_TOKEN_KEY);
  +
  +            // Retrieve the transaction token included in this request
  +            String token = (String) request.getParameter(Constants.TOKEN_KEY);
  +            if (token == null)
  +                return (false);
  +
  +            // Do the values match?
  +            return (saved.equals(token));
  +
  +        }
   
       }