Extensible Messaging and Presence Protocol (XMPP): Core
Extracted elements (27)
TLS negotiation MUST be completed before SASL negotiation because completing SASL first would expose authentication credentials to eavesdropping; this layering order (TCP → TLS → SASL → XMPP) ensures the channel is encrypted before any authentication data is transmitted.
XMPP uses persistent, long-lived XML streams over TCP rather than stateless request-response connections, enabling either party to push data at any time. This 'Availability for Concurrent Transactions' (ACT) model is intentionally distinct from REST, enabling near-real-time communication where knowledge of peer availability precedes message exchange.
At the time of publication, most deployed servers use Server Dialback (XEP-0220) for weak server identity verification rather than SASL with PKIX certificates, particularly when TLS is not mandated by the peer or when peer certificates are self-signed. RFC 6120 specifies the stronger SASL+PKIX approach but acknowledges the existing deployment base.
A server MUST process XML stanzas from a given sender in the order received and MUST NOT deliver stanzas from a given sender out of order, ensuring that a receiver processes stanzas in the sequence they were sent.
An initiating entity (client or server) MUST open a TCP connection to the receiving entity before negotiating XML streams, and the parties MUST maintain that TCP connection for as long as the XML streams are in use.
For client-to-server streams, the client's bare JID MUST be the SASL authorization identity and the resourcepart MUST be negotiated during resource binding; a client MUST NOT guess its JID but MUST treat the JID returned by the server during resource binding as authoritative.
If an initiating entity receives a response to its SRV query but cannot establish an XMPP connection, it SHOULD NOT attempt the A/AAAA fallback process (to prevent inbound/outbound state mismatch); if no SRV response is received, it SHOULD attempt fallback using port 5222 (client-to-server) or 5269 (server-to-server).
On reconnection, an entity SHOULD use an unpredictable delay between 0 and 60 seconds before reconnecting and SHOULD apply truncated binary exponential backoff on subsequent attempts. TLS session resumption is RECOMMENDED when reconnecting.
On successful negotiation of a feature that requires a stream restart (e.g., TLS or SASL with a security layer), both parties MUST NOT send a closing </stream> tag and MUST NOT terminate the underlying TCP connection; instead, the initiating entity MUST send a new initial stream header over the existing connection and the receiving entity MUST generate a new stream ID.
Resource binding is mandatory-to-negotiate for client-to-server streams. After SASL success the server MUST advertise the resource binding feature, and a client MUST complete resource binding before it may send XML stanzas to entities other than the connected server.
SASL negotiation is mandatory-to-negotiate for both client-to-server and server-to-server streams; both the initiating entity and receiving entity MUST support SASL. After successful SASL exchange the initiating entity MUST send a new initial stream header to restart the stream.
The initiating entity MUST NOT send XML stanzas to entities other than itself or the connected server until stream negotiation is complete; if it does, the receiving entity MUST NOT accept such stanzas and MUST close the stream with a <not-authorized/> stream error.
When closing an XML stream, to prevent truncation attacks the closing party MUST send a TLS close_notify alert per RFC 5246 Section 7.2.1 and MUST receive a responding close_notify from the other party before terminating the underlying TCP connection.
When STARTTLS is advertised as mandatory-to-negotiate (via a <required/> child element in the feature advertisement), the initiating entity MUST negotiate TLS before proceeding with any further stream negotiation, including SASL authentication.
XMPP servers can reveal IP address information to peer servers and potentially to clients via stanza routing metadata; presence information (availability, status, timestamps) can expose user activity patterns to contacts and servers. Implementations should limit what stream metadata is exposed beyond what the protocol requires.
After sending its response stream header, the receiving entity MUST send a <stream:features/> element advertising mandatory-to-negotiate and voluntary-to-negotiate features. An empty <features/> element or one containing only voluntary features signals negotiation is complete and the initiating entity is cleared to send XML stanzas.
An XML stream is a container for XML element exchange delimited by an opening <stream> tag and closing </stream> tag. An XML stanza is a first-level element (depth=1) whose name is 'message', 'presence', or 'iq' and whose qualifying namespace is 'jabber:client' or 'jabber:server'; no other element at depth=1 qualifies as a stanza.
IQ (Info/Query) stanzas implement a request-response mechanism using a required 'type' attribute of 'get', 'set', 'result', or 'error', and a required 'id' attribute that links a result or error to the originating get or set. A server MUST reply to each get or set it receives with either a result or error having the same 'id' value.
Stream errors are unrecoverable; upon encountering one, the entity MUST send a <stream:error/> element containing a defined-condition child in namespace 'urn:ietf:params:xml:ns:xmpp-streams', then send a closing </stream> tag. Defined conditions include: bad-format, conflict, connection-timeout, host-unknown, invalid-namespace, not-authorized, not-well-formed, policy-violation, resource-constraint, see-other-host, system-shutdown, and others.
This document registers five XML namespace names with IANA: 'urn:ietf:params:xml:ns:xmpp-tls', 'urn:ietf:params:xml:ns:xmpp-sasl', 'urn:ietf:params:xml:ns:xmpp-streams', 'urn:ietf:params:xml:ns:xmpp-bind', and 'urn:ietf:params:xml:ns:xmpp-stanzas'. It also registers the GSSAPI service name 'xmpp' and confirms TCP port 5222 (xmpp-client) and port 5269 (xmpp-server).
For confidentiality and password-based authentication, implementations MUST support TLS with the TLS_RSA_WITH_AES_128_CBC_SHA cipher suite and SASL SCRAM-SHA-1 as mandatory-to-implement technologies, establishing a common security baseline across all conforming XMPP implementations.
Implementations MUST validate server TLS certificates per RFC 6125 procedures; the server certificate MUST contain a DNS-ID or SRV-ID that matches the XMPP service's origin domain. Self-signed certificates or certificates without a matching identifier MUST NOT be accepted without explicit prior out-of-band acceptance.
The 'see-other-host' stream error can be used to redirect an initiating entity to a different host; implementations MUST verify that the redirected hostname is authorized to serve the target domain to prevent an attacker from exploiting this feature to perform a man-in-the-middle attack.
XMPP services are susceptible to denial-of-service attacks including large XML stanza floods, deeply nested XML structures (XML bombs), excessive connection attempts, and excessive IQ requests. Servers SHOULD implement rate limiting, maximum stanza sizes, XML nesting depth limits, and connection throttling.
Stream negotiation states: OPEN TCP → SEND INITIAL HEADER → RECEIVE RESPONSE HEADER → RECEIVE FEATURES. From FEATURES: if empty → DONE; if all voluntary → MAY negotiate, then DONE; if mandatory present → MUST negotiate one feature → if restart required, loop to SEND INITIAL HEADER; else return to RECEIVE FEATURES. TLS must precede SASL, which must precede resource binding.
A stanza error is conveyed as a child <error/> element carrying a required 'type' attribute (auth, cancel, continue, modify, or wait) and a defined-condition child element in the 'urn:ietf:params:xml:ns:xmpp-stanzas' namespace, optionally followed by a human-readable <text/> element and application-specific conditions in other namespaces.
The stream header (<stream:stream>) carries five defined attributes: 'from' (sender JID), 'to' (receiver domain), 'id' (server-generated unique opaque stream identifier), 'xml:lang' (default natural language), and 'version' (must be '1.0' for XMPP 1.0). The stream namespace prefix maps to 'http://etherx.jabber.org/streams'.