Uploaded image for project: 'ejabberd development'
  1. ejabberd development
  2. EJAB-569

SASL digest authentication does not check digest-uri

    Details

      Description

      XMPP specification is vague about SASL specification and digest-uri. It only mentions the example xmpp/example.com which suggests that the proper URI is xmpp/ + FQDN.

      SASL digest specification mentions that the server SHOULD check the digest-uri to make sure the client is connecting to the server it thinks it is connecting to.

      ejabberd does not check the digest-uri and therefore allows for proxies that fool clients and ejabberd and relay their authentication:

      client <--> proxy at proxy.com <--> server at server.com

      The client authenticates to with xmpp/proxy.com as the digest-uri and then the proxy relays the packet and ejabberd accepts this token while it should not. The attached patch is a quick fix for that and verifies that the digest-uri is exactly xmpp/<FQDN>. This works for us, but it definitely should be enhanced to be included upstream with a case insensitive check and maybe allowing xmpp/<IP>.

        Issue Links

          Expenses

            Activity

            Hide
            pguyot Paul Guyot added a comment -

            Quick patch against ejabberd 2.0.0.

            Show
            pguyot Paul Guyot added a comment - Quick patch against ejabberd 2.0.0.
            Hide
            badlop Badlop added a comment - - edited

            Reference documents:

            1. 'XMPP specification is vague about SASL'

            In XMPP-Core [1] it says:

            Step 6: Client sends a [BASE64] encoded response to the challenge:
            ...
            The decoded response is:
            username="somenode",realm="somerealm",\
            nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
            nc=00000001,qop=auth,digest-uri="xmpp/example.com",\
            response=d388dad90d4bbd760a152321f2143af7,charset=utf-8

            The examples are not included in draft-saintandre-rfc3920bis-05.

            2. 'SASL digest specification mentions that the server SHOULD check the digest-uri'

            In RFC-2831: Using Digest Authentication as a SASL Mechanism [2] it is explained the syntax of the digest response:

               digest-response  = 1#( username | realm | nonce | cnonce |
                                      nonce-count | qop | digest-uri | response |
                                      maxbuf | charset | cipher | authzid |
                                      auth-param )
            
                   ...
                   digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
                   digest-uri-value  = serv-type "/" host [ "/" serv-name ]
                   serv-type        = 1*ALPHA
                   host             = 1*( ALPHA | DIGIT | "-" | "." )
                   serv-name        = host
                   ...
            

            Its explanation is:

            serv-type
                  Indicates the type of service, such as "www" for web service,
                  "ftp" for FTP service, "smtp" for mail delivery service, etc. The
                  service name as defined in the SASL profile for the protocol see
                  section 4 of [RFC 2222], registered in the IANA registry of
                  "service" elements for the GSSAPI host-based service name form
                  [RFC 2078].
            
            host
                  The DNS host name or IP address for the service requested.  The
                  DNS host name must be the fully-qualified canonical name of the
                  host. The DNS host name is the preferred form; see notes on server
                  processing of the digest-uri.
            
            serv-name
                  Indicates the name of the service if it is replicated. The service
                  is considered to be replicated if the client's service-location
                  process involves resolution using standard DNS lookup operations,
                  and if these operations involve DNS records (such as SRV, or MX)
                  which resolve one DNS name into a set of other DNS names. In this
                  case, the initial name used by the client is the "serv-name", and
                  the final name is the "host" component. For example, the incoming
                  mail service for "example.com" may be replicated through the use
                  of MX records stored in the DNS, one of which points at an SMTP
                  server called "mail3.example.com"; it's "serv-name" would be
                  "example.com", it's "host" would be "mail3.example.com". If the
                  service is not replicated, or the serv-name is identical to the
                  host, then the serv-name component MUST be omitted.
            
            digest-uri
                  Indicates the principal name of the service with which the client
                  wishes to connect, formed from the serv-type, host, and serv-name.
                  For example, the FTP service on "ftp.example.com" would have a
                  "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from
                  the example above would have a "digest-uri" value of
                  "smtp/mail3.example.com/example.com".
            
               Servers SHOULD check that the supplied value is correct. This will
               detect accidental connection to the incorrect server. It is also so
               that clients will be trained to provide values that will work with
               implementations that use a shared back-end authentication service
               that can provide server authentication.
            
               The serv-type component should match the service being offered. The
               host component should match one of the host names of the host on
               which the service is running, or it's IP address. Servers SHOULD NOT
               normally support the IP address form, because server authentication
               by IP address is not very useful; they should only do so if the DNS
               is unavailable or unreliable. The serv-name component should match
               one of the service's configured service names.
            
               This directive may appear at most once; if multiple instances are
               present, the client should abort the authentication exchange.
            
               Note: In the HTTP use of Digest authentication, the digest-uri is the
               URI (usually a URL) of the resource requested -- hence the name of
               the directive.
            

            [1] http://www.xmpp.org/rfcs/rfc3920.html
            [2] ftp://ftp.isi.edu/in-notes/rfc2831.txt

            Show
            badlop Badlop added a comment - - edited Reference documents: 1. 'XMPP specification is vague about SASL' In XMPP-Core [1] it says: Step 6: Client sends a [BASE64] encoded response to the challenge: ... The decoded response is: username="somenode",realm="somerealm",\ nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\ nc=00000001,qop=auth,digest-uri="xmpp/example.com",\ response=d388dad90d4bbd760a152321f2143af7,charset=utf-8 The examples are not included in draft-saintandre-rfc3920bis-05. 2. 'SASL digest specification mentions that the server SHOULD check the digest-uri' In RFC-2831: Using Digest Authentication as a SASL Mechanism [2] it is explained the syntax of the digest response: digest-response = 1#( username | realm | nonce | cnonce | nonce-count | qop | digest-uri | response | maxbuf | charset | cipher | authzid | auth-param ) ... digest-uri = "digest-uri" "=" < "> digest-uri-value <" > digest-uri-value = serv-type "/" host [ "/" serv-name ] serv-type = 1*ALPHA host = 1*( ALPHA | DIGIT | "-" | "." ) serv-name = host ... Its explanation is: serv-type Indicates the type of service, such as "www" for web service, "ftp" for FTP service, "smtp" for mail delivery service, etc. The service name as defined in the SASL profile for the protocol see section 4 of [RFC 2222], registered in the IANA registry of "service" elements for the GSSAPI host-based service name form [RFC 2078]. host The DNS host name or IP address for the service requested. The DNS host name must be the fully-qualified canonical name of the host. The DNS host name is the preferred form; see notes on server processing of the digest-uri. serv-name Indicates the name of the service if it is replicated. The service is considered to be replicated if the client's service-location process involves resolution using standard DNS lookup operations, and if these operations involve DNS records (such as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case , the initial name used by the client is the "serv-name" , and the final name is the "host" component. For example, the incoming mail service for "example.com" may be replicated through the use of MX records stored in the DNS, one of which points at an SMTP server called "mail3.example.com" ; it's "serv-name" would be "example.com" , it's "host" would be "mail3.example.com" . If the service is not replicated, or the serv-name is identical to the host, then the serv-name component MUST be omitted. digest-uri Indicates the principal name of the service with which the client wishes to connect, formed from the serv-type, host, and serv-name. For example, the FTP service on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com" ; the SMTP server from the example above would have a "digest-uri" value of "smtp/mail3.example.com/example.com" . Servers SHOULD check that the supplied value is correct. This will detect accidental connection to the incorrect server. It is also so that clients will be trained to provide values that will work with implementations that use a shared back-end authentication service that can provide server authentication. The serv-type component should match the service being offered. The host component should match one of the host names of the host on which the service is running, or it's IP address. Servers SHOULD NOT normally support the IP address form, because server authentication by IP address is not very useful; they should only do so if the DNS is unavailable or unreliable. The serv-name component should match one of the service's configured service names. This directive may appear at most once; if multiple instances are present, the client should abort the authentication exchange. Note: In the HTTP use of Digest authentication, the digest-uri is the URI (usually a URL) of the resource requested -- hence the name of the directive. [1] http://www.xmpp.org/rfcs/rfc3920.html [2] ftp://ftp.isi.edu/in-notes/rfc2831.txt
            Hide
            badlop Badlop added a comment -

            I improved the patch provided by Paul Guyot:

            1. It's now case insensitive

            2. Allows clients to provide a complex digest-uri like:
            xmpp/server3.example.org/jabber.example.org
            As mentioned in the RFC, such string is used when the same service is provided by several hosts.

            I didn't implement support for IP addresses, because the RFC says that servers should not allow it, and in fact it's difficult to implement.

            I tested this patch in a simple server with Tkabber, Psi and Gajim. I guess some client will have problems with this new digest-uri check. And probably the only way to let those problems surface and be fixed is to commit to SVN trunk early and wait for reports.

            Show
            badlop Badlop added a comment - I improved the patch provided by Paul Guyot: 1. It's now case insensitive 2. Allows clients to provide a complex digest-uri like: xmpp/server3.example.org/jabber.example.org As mentioned in the RFC, such string is used when the same service is provided by several hosts. I didn't implement support for IP addresses, because the RFC says that servers should not allow it, and in fact it's difficult to implement. I tested this patch in a simple server with Tkabber, Psi and Gajim. I guess some client will have problems with this new digest-uri check. And probably the only way to let those problems surface and be fixed is to commit to SVN trunk early and wait for reports.
            Hide
            badlop Badlop added a comment -

            Patch applied to trunk and 2.0.x branch in SVN r1743.

            Show
            badlop Badlop added a comment - Patch applied to trunk and 2.0.x branch in SVN r1743.

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Development