WSS4J
  1. WSS4J
  2. WSS-54

UsernameTokenProcessor not processing unhashed UsernameToken

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.5.4
    • Component/s: None
    • Labels:
      None

      Description

      The UsernameTokenProcessor will not authenticate anything but a UsernameToken that was hashed with a nonce and timestamp. Anything else that is passed to it will create a valid principal regardless of what the implementations password callback handler does. This is creating confusion and preventing WSS4J from being used for anything where the the UsernameToken is passed plainly. It is understood that doing this in a production environment is discouraged, but it is usefull to have this implementation work as expected so that the framework can be experimented with and evaluated.

      Specifically, in UsernameTokenProcessor.java, for a UsernameToken that is not of hashed, nothing is done with the WSPasswordCallback object after the call to the password handler handle method is invoked. Since nothing is done with it, the code drops through and sets up a valid principal with the userid and returns. There is no way to signal a WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION).

      1. wss4j_wss54_revised.patch
        19 kB
        Colm O hEigeartaigh

        Issue Links

          Activity

          Bob Coss created issue -
          Hide
          Ruchith Udayanga Fernando added a comment -

          Actually the callback handler is called in the case when the password is not a hashed password.

          In this case the both username and password values from the UsernameToken element are set in the WSPasswordCallback instance sent into the callback handler. Usage flag of the WSPasswordCallback is set to WSPasswordCallback.USERNAME_TOKEN_UNKNOWN. One can carryout authentication of the user at the callback with this information within the callback handler. See line : 123-136 of UsernameTokenProcessor[1] (svn revision - 438091 - right now).

          A simple example of a callback handler implementation can be found here [2]

          [1] https://svn.apache.org/repos/asf/webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java
          [2] https://svn.apache.org/repos/asf/webservices/axis2/trunk/java/modules/integration/test/org/apache/axis2/security/sc/PWCallback.java

          Show
          Ruchith Udayanga Fernando added a comment - Actually the callback handler is called in the case when the password is not a hashed password. In this case the both username and password values from the UsernameToken element are set in the WSPasswordCallback instance sent into the callback handler. Usage flag of the WSPasswordCallback is set to WSPasswordCallback.USERNAME_TOKEN_UNKNOWN. One can carryout authentication of the user at the callback with this information within the callback handler. See line : 123-136 of UsernameTokenProcessor [1] (svn revision - 438091 - right now). A simple example of a callback handler implementation can be found here [2] [1] https://svn.apache.org/repos/asf/webservices/wss4j/trunk/src/org/apache/ws/security/processor/UsernameTokenProcessor.java [2] https://svn.apache.org/repos/asf/webservices/axis2/trunk/java/modules/integration/test/org/apache/axis2/security/sc/PWCallback.java
          Hide
          Bob Coss added a comment -

          [[ Old comment, sent by email on Tue, 29 Aug 2006 10:28:05 -0500 ]]

          That doesn't seem to make sense to me the way this is handled.
          According to the way the callback is being processed, the only thing
          that can be thrown is a UnsupportedCallbackException() or IOException.
          In UsernameTokenProcessor, it will throw:

          throw new WSSecurityException(WSSecurityException.FAILURE,
          "noPassword", new Object[]

          {user}

          );

          and not a
          WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION).

          In the spirit of JAAS, shouldn't the handler be providing the value of
          the password to the callback, and the UsernameTokoenProcessor evaluating
          the password supplied in the token with the one from application?

          Show
          Bob Coss added a comment - [[ Old comment, sent by email on Tue, 29 Aug 2006 10:28:05 -0500 ]] That doesn't seem to make sense to me the way this is handled. According to the way the callback is being processed, the only thing that can be thrown is a UnsupportedCallbackException() or IOException. In UsernameTokenProcessor, it will throw: throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] {user} ); and not a WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION). In the spirit of JAAS, shouldn't the handler be providing the value of the password to the callback, and the UsernameTokoenProcessor evaluating the password supplied in the token with the one from application?
          Hide
          Ever A. Olano added a comment -

          I think I can live with the callback handler determining from the usage (USERNAME_TOKEN or USERNAME_TOKEN_UNKNOWN) whether or not to do the validation itself. However, In UsernameTokenProcessor.java:

          } else if (cb != null) {
          WSPasswordCallback pwCb = new WSPasswordCallback(user, password,
          pwType, WSPasswordCallback.USERNAME_TOKEN_UNKNOWN);
          callbacks[0] = pwCb;
          try

          { cb.handle(callbacks); }

          catch (IOException e) {
          throw new WSSecurityException(WSSecurityException.FAILURE,
          "noPassword", new Object[]

          {user});
          } catch (UnsupportedCallbackException e) {
          throw new WSSecurityException(WSSecurityException.FAILURE,
          "noPassword", new Object[]{user}

          );
          }
          }

          It should throw FAILED_AUTHENTICATION instead of FAILURE. Either that or have another exception, say, FailedAuthenticationException that cb.handle() may throw so that this code can differentiate between a real "noPassword" scenario or a failed authentication.

          By the way, this is probably being nitpicky, but we should probably get rid of the "noPassword" resource and return the same error message for failed authentication instead. That way, a hacker would not be able to tell whether or not the username they tried to authenticate with exists.

          Thanks,
          Ever

          Show
          Ever A. Olano added a comment - I think I can live with the callback handler determining from the usage (USERNAME_TOKEN or USERNAME_TOKEN_UNKNOWN) whether or not to do the validation itself. However, In UsernameTokenProcessor.java: } else if (cb != null) { WSPasswordCallback pwCb = new WSPasswordCallback(user, password, pwType, WSPasswordCallback.USERNAME_TOKEN_UNKNOWN); callbacks [0] = pwCb; try { cb.handle(callbacks); } catch (IOException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] {user}); } catch (UnsupportedCallbackException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[]{user} ); } } It should throw FAILED_AUTHENTICATION instead of FAILURE. Either that or have another exception, say, FailedAuthenticationException that cb.handle() may throw so that this code can differentiate between a real "noPassword" scenario or a failed authentication. By the way, this is probably being nitpicky, but we should probably get rid of the "noPassword" resource and return the same error message for failed authentication instead. That way, a hacker would not be able to tell whether or not the username they tried to authenticate with exists. Thanks, Ever
          Hide
          Ever A. Olano added a comment -

          I just reread the last paragraph that I wrote and feel that I need to clarify it. I think, what I wish to happen is that everywhere it throws FAILURE with "noPassword" as the resource, it should instead throw FAILED_AUTHENTICATION. i.e. same error message for "non-existent username/password" and "invalid password".

          Hope that's clearer.

          Thanks again,
          Ever

          Show
          Ever A. Olano added a comment - I just reread the last paragraph that I wrote and feel that I need to clarify it. I think, what I wish to happen is that everywhere it throws FAILURE with "noPassword" as the resource, it should instead throw FAILED_AUTHENTICATION. i.e. same error message for "non-existent username/password" and "invalid password". Hope that's clearer. Thanks again, Ever
          Davanum Srinivas made changes -
          Field Original Value New Value
          Assignee Davanum Srinivas [ dims ]
          Colm O hEigeartaigh made changes -
          Link This issue is duplicated by WSS-98 [ WSS-98 ]
          Hide
          Colm O hEigeartaigh added a comment -

          Please see the attached patch for a solution to this problem. The patch contains four things:

          1) More extensive testing of processing Username Tokens.

          2) Standard FAILED_AUTHENTICATION error codes are now returned, as suggested by Evan. In this way, no information is leaked to a potential attacker.

          3) The UsernameTokenProcessor now does the authentication for both plaintext and password digest types. In both these cases, the sole function of the callback is to supply the password. This is more consistent than the existing solution.

          4) By default custom password types are rejected. However, a configuration variable is added to WSSConfig and WSHandlerConstants, which enables the UsernameTokenProcessor to handle custom password types. In this case, all authentication is delegated to the callback handler. The reason they are rejected by default is to avoid a potential security hole when the implementing callback handler code leaves out a test for USERNAME_TOKEN_UNKNOWN.

          Show
          Colm O hEigeartaigh added a comment - Please see the attached patch for a solution to this problem. The patch contains four things: 1) More extensive testing of processing Username Tokens. 2) Standard FAILED_AUTHENTICATION error codes are now returned, as suggested by Evan. In this way, no information is leaked to a potential attacker. 3) The UsernameTokenProcessor now does the authentication for both plaintext and password digest types. In both these cases, the sole function of the callback is to supply the password. This is more consistent than the existing solution. 4) By default custom password types are rejected. However, a configuration variable is added to WSSConfig and WSHandlerConstants, which enables the UsernameTokenProcessor to handle custom password types. In this case, all authentication is delegated to the callback handler. The reason they are rejected by default is to avoid a potential security hole when the implementing callback handler code leaves out a test for USERNAME_TOKEN_UNKNOWN.
          Colm O hEigeartaigh made changes -
          Attachment wss4j_wss54.patch [ 12380066 ]
          Colm O hEigeartaigh made changes -
          Attachment wss4j_wss54.patch [ 12380066 ]
          Hide
          Colm O hEigeartaigh added a comment -

          Here is a revised patch for this issue. This patch preserves the original functionality whereby the authentication of plaintext password or unknown password types is delegated to the callback handler. We really need to revisit this architecture for 2.0, as the callback handler architecture is not being used correctly.

          This patch contains three things:

          1) More extensive testing of processing Username Tokens.

          2) Standard FAILED_AUTHENTICATION error codes are now returned, as suggested by Evan. In this way, no information is leaked to a potential attacker.

          3) By default custom password types are rejected. However, a configuration variable is added to WSSConfig and WSHandlerConstants, which enables the UsernameTokenProcessor to handle custom password types. In this case, all authentication is delegated to the callback handler.

          Show
          Colm O hEigeartaigh added a comment - Here is a revised patch for this issue. This patch preserves the original functionality whereby the authentication of plaintext password or unknown password types is delegated to the callback handler. We really need to revisit this architecture for 2.0, as the callback handler architecture is not being used correctly. This patch contains three things: 1) More extensive testing of processing Username Tokens. 2) Standard FAILED_AUTHENTICATION error codes are now returned, as suggested by Evan. In this way, no information is leaked to a potential attacker. 3) By default custom password types are rejected. However, a configuration variable is added to WSSConfig and WSHandlerConstants, which enables the UsernameTokenProcessor to handle custom password types. In this case, all authentication is delegated to the callback handler.
          Colm O hEigeartaigh made changes -
          Attachment wss4j_wss54_revised.patch [ 12380162 ]
          Hide
          Fred Dushin added a comment -

          Applied Colm's patch, which has been reviewed on the list.

          Show
          Fred Dushin added a comment - Applied Colm's patch, which has been reviewed on the list.
          Fred Dushin made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Fred Dushin made changes -
          Fix Version/s 1.5.4 [ 12313167 ]
          Hide
          Fred Dushin added a comment -

          Bulk change of "Fix Version" for all issues fixed or closed for 1.5.4

          Show
          Fred Dushin added a comment - Bulk change of "Fix Version" for all issues fixed or closed for 1.5.4
          Colm O hEigeartaigh made changes -
          Status Resolved [ 5 ] Closed [ 6 ]
          Transition Time In Source Status Execution Times Last Executer Last Execution Date
          Open Open Resolved Resolved
          597d 2h 19m 1 Fred Dushin 17/Apr/08 17:56
          Resolved Resolved Closed Closed
          1263d 16h 6m 1 Colm O hEigeartaigh 03/Oct/11 10:02

            People

            • Assignee:
              Unassigned
              Reporter:
              Bob Coss
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development