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

          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