19. Security Framework
The RTSP security framework consists of two high-level components: the pure authentication mechanisms based on HTTP authentication and the message transport protection based on TLS, which is independent of RTSP. Because of the similarity in syntax and usage between RTSP servers and HTTP servers, the security for HTTP is reused to a large extent.19.1. RTSP and HTTP Authentication
RTSP and HTTP share common authentication schemes; thus, they follow the same framework as specified in [RFC7235]. RTSP uses the corresponding RTSP error codes (401 and 407) and headers (WWW- Authenticate, Authorization, Proxy-Authenticate, Proxy-Authorization) by importing the definitions from [RFC7235]. Servers SHOULD implement both the Basic [RFC7617] and the Digest [RFC7616] authentication schemes. Clients MUST implement both the Basic and the Digest authentication schemes so that a server that requires the client to authenticate can trust that the capability is present. If implementing the Digest authentication scheme, then the additional considerations specified below in Section 19.1.1 MUST be followed.
It should be stressed that using the HTTP authentication alone does not provide full RTSP message security. Therefore, TLS SHOULD be used; see Section 19.2. Any RTSP message containing an Authorization header using the Basic authentication scheme MUST be using a TLS connection with confidentiality protection enabled, i.e., no NULL encryption. In cases where there is a chain of proxies between the client and the server, each proxy may individually request the client or previous proxy to authenticate itself. This is done using the Proxy- Authenticate (Section 18.34), the Proxy-Authorization (Section 18.36), and the Proxy-Authentication-Info (Section 18.35) headers. These headers are hop-by-hop headers and are only scoped to the current connection and hop. Thus, if a proxy chain exists, a proxy connecting to another proxy will have to act as a client to authorize itself towards the next proxy. The WWW-Authenticate (Section 18.58), Authorization (Section 18.8), and Authentication- Info (Section 18.7) headers are end-to-end and MUST NOT be modified by proxies. This authentication mechanism works only for client-to-server requests as currently defined. This leaves server-to-client request outside of the context of TLS-based communication more vulnerable to message-injection attacks on the client. Based on the server-to- client methods that exist, the potential risks are various: hijacking (REDIRECT), denial of service (TEARDOWN and PLAY_NOTIFY), or attacks with uncertain results (SET_PARAMETER).19.1.1. Digest Authentication
This section describes the modifications and clarifications required to apply the HTTP Digest authentication scheme to RTSP. The RTSP scheme usage is almost completely identical to that for HTTP [RFC7616]. These modifications are based on the procedures defined for SIP 2.0 [RFC3261] (in Section 22.4) but updated to use RFC 7235, RFC 7616 and RFC 7615 instead of RFC 2617. Digest authentication uses two additional headers, Authentication- Info and Proxy-Authentication-Info, that are defined as in [RFC7615]. The rules for Digest authentication follow those defined in [RFC7616], with "HTTP/1.1" replaced by "RTSP/2.0" in addition to the following differences: 1. Use the ABNF specified in the referenced documents, with the difference that the URI parameter uses the request URI format for RTSP, i.e. the ABNF element: Request-URI (see Section 20.2.1). The domain parameter uses the RTSP-URI-Ref element for absolute and relative URIs.
2. If MTags are used, then the example procedure for choosing a nonce based on ETag can work, based on replacing the ETag with the MTag. 3. As a clarification to the calculation of the A2 value for message integrity assurance in the Digest authentication scheme, implementers should assume, when the entity-body is empty (that is, when the RTSP messages have no message body) that the hash of the message body resolves to the hash of an empty string, or: H(entity-body), example MD5("") = "d41d8cd98f00b204e9800998ecf8427e".19.2. RTSP over TLS
RTSP agents MUST implement RTSP over TLS as defined in this section and the next Section 19.3. RTSP MUST follow the same guidelines with regard to TLS [RFC5246] usage as specified for HTTP; see [RFC2818]. RTSP over TLS is separated from unsecured RTSP both on the URI level and the port level. Instead of using the "rtsp" scheme identifier in the URI, the "rtsps" scheme identifier MUST be used to signal RTSP over TLS. If no port is given in a URI with the "rtsps" scheme, port 322 MUST be used for TLS over TCP/IP. When a client tries to set up an insecure channel to the server (using the "rtsp" URI), and the policy for the resource requires a secure channel, the server MUST redirect the client to the secure service by sending a 301 redirect response code together with the correct Location URI (using the "rtsps" scheme). A user or client MAY upgrade a non secured URI to a secured by changing the scheme from "rtsp" to "rtsps". A server implementing support for "rtsps" MUST allow this. It should be noted that TLS allows for mutual authentication (when using both server and client certificates). Still, one of the more common ways TLS is used is to provide only server-side authentication (often to avoid client certificates). TLS is then used in addition to HTTP authentication, providing transport security and server authentication, while HTTP Authentication is used to authenticate the client. RTSP includes the possibility to keep a TCP session up between the client and server, throughout the RTSP session lifetime. It may be convenient to keep the TCP session, not only to save the extra setup time for TCP, but also the extra setup time for TLS (even if TLS uses the resume function, there will be almost two extra round trips). Still, when TLS is used, such behavior introduces extra active state in the server, not only for TCP and RTSP, but also for TLS. This may increase the vulnerability to DoS attacks.
There exists a potential security vulnerability when reusing TCP and TLS state for different resources (URIs). If two different hostnames point at the same IP address, it can be desirable to reuse the TCP/ TLS connection to that server. In that case, the RTSP agent having the TCP/TLS connection MUST verify that the server certificate associated with the connection has a SubjectAltName matching the hostname present in the URI for the resource an RTSP request is to be issued. In addition to these recommendations, Section 19.3 gives further recommendations of TLS usage with proxies.19.3. Security and Proxies
The nature of a proxy is often to act as a "man in the middle", while security is often about preventing the existence of one. This section provides clients with the possibility to use proxies even when applying secure transports (TLS) between the RTSP agents. The TLS proxy mechanism allows for server and proxy identification using certificates. However, the client cannot be identified based on certificates. The client needs to select between using the procedure specified below or using a TLS connection directly (bypassing any proxies) to the server. The choice may be dependent on policies. In general, there are two categories of proxies: the transparent proxies (of which the client is not aware) and the non-transparent proxies (of which the client is aware). This memo specifies only non-transparent RTSP proxies, i.e., proxies visible to the RTSP client and RTSP server. An infrastructure based on proxies requires that the trust model be such that both client and server can trust the proxies to handle the RTSP messages correctly. To be able to trust a proxy, the client and server also need to be aware of the proxy. Hence, transparent proxies cannot generally be seen as trusted and will not work well with security (unless they work only at the transport layer). In the rest of this section, any reference to "proxy" will be to a non-transparent proxy, which inspects or manipulates the RTSP messages. HTTP Authentication is built on the assumption of proxies and can provide user-proxy authentication and proxy-proxy/server authentication in addition to the client-server authentication. When TLS is applied and a proxy is used, the client will connect to the proxy's address when connecting to any RTSP server. This implies that for TLS, the client will authenticate the proxy server and not the end server. Note that when the client checks the server
certificate in TLS, it MUST check the proxy's identity (URI or possibly other known identity) against the proxy's identity as presented in the proxy's Certificate message. The problem is that for a proxy accepted by the client, the proxy needs to be provided information on which grounds it should accept the next-hop certificate. Both the proxy and the user may have rules for this, and the user should have the possibility to select the desired behavior. To handle this case, the Accept-Credentials header (see Section 18.2) is used, where the client can request the proxy or proxies to relay back the chain of certificates used to authenticate any intermediate proxies as well as the server. The assumption that the proxies are viewed as trusted gives the user a possibility to enforce policies on each trusted proxy of whether it should accept the next agent in the chain. However, it should be noted that not all deployments will return the chain of certificates used to authenticate any intermediate proxies as well as the server. An operator of such a deployment may want to hide its topology from the client. It should be noted well that the client does not have any insight into the proxy's operation. Even if the proxy is trusted, it can still return an incomplete chain of certificates. A proxy MUST use TLS for the next hop if the RTSP request includes an "rtsps" URI. TLS MAY be applied on intermediate links (e.g., between client and proxy or between proxy and proxy) even if the resource and the end server are not required to use it. The chain of proxies used by a client to reach a server and its TLS sessions MUST have commensurate security. Therefore, a proxy MUST, when initiating the next-hop TLS connection, use the incoming TLS connections cipher- suite list, only modified by removing any cipher suites that the proxy does not support. In case a proxy fails to establish a TLS connection due to cipher-suite mismatch between proxy and next-hop proxy or server, this is indicated using error code 472 (Failure to Establish Secure Connection).19.3.1. Accept-Credentials
The Accept-Credentials header can be used by the client to distribute simple authorization policies to intermediate proxies. The client includes the Accept-Credentials header to dictate how the proxy treats the server / next proxy certificate. There are currently three methods defined: Any: With "any", the proxy (or proxies) MUST accept whatever certificate is presented. Of course, this is not a recommended option to use, but it may be useful in certain circumstances (such as testing).
Proxy: For the "proxy" method, the proxy (or proxies) MUST use its own policies to validate the certificate and decide whether or not to accept it. This is convenient in cases where the user has a strong trust relation with the proxy. Reasons why a strong trust relation may exist are personal/company proxy or the proxy has an out-of-band policy configuration mechanism. User: For the "user" method, the proxy (or proxies) MUST send credential information about the next hop to the client for authorization. The client can then decide whether or not the proxy should accept the certificate. See Section 19.3.2 for further details. If the Accept-Credentials header is not included in the RTSP request from the client, then the "Proxy" method MUST be used as default. If a method other than the "Proxy" is to be used, then the Accept- Credentials header MUST be included in all of the RTSP requests from the client. This is because it cannot be assumed that the proxy always keeps the TLS state or the user's previous preference between different RTSP messages (in particular, if the time interval between the messages is long). With the "Any" and "Proxy" methods, the proxy will apply the policy as defined for each method. If the policy does not accept the credentials of the next hop, the proxy MUST respond with a message using status code 471 (Connection Credentials Not Accepted). An RTSP request in the direction server to client MUST NOT include the Accept-Credentials header. As for the non-secured communication, the possibility for these requests depends on the presence of a client established connection. However, if the server-to-client request is in relation to a session established over a TLS secured channel, it MUST be sent in a TLS secured connection. That secured connection MUST also be the one used by the last client-to-server request. If no such transport connection exists at the time when the server desires to send the request, the server MUST discard the message. Further policies MAY be defined and registered, but this should be done with caution.19.3.2. User-Approved TLS Procedure
For the "User" method, each proxy MUST perform the following procedure for each RTSP request: o Set up the TLS session to the next hop if not already present (i.e., run the TLS handshake, but do not send the RTSP request).
o Extract the peer certificate chain for the TLS session. o Check if a matching identity and hash of the peer certificate are present in the Accept-Credentials header. If present, send the message to the next hop and conclude these procedures. If not, go to the next step. o The proxy responds to the RTSP request with a 470 or 407 response code. The 407 response code MAY be used when the proxy requires both user and connection authorization from user or client. In this message the proxy MUST include a Connection-Credentials header, see Section 18.13, with the next hop's identity and certificate. The client MUST upon receiving a 470 (Connection Authorization Required) or 407 (Proxy Authentication Required) response with Connection-Credentials header take the decision on whether or not to accept the certificate (if it cannot do so, the user SHOULD be consulted). Using IP addresses in the next-hop URI and certificates rather than domain names makes it very difficult for a user to determine whether or not it should approve the next hop. Proxies are RECOMMENDED to use domain names to identify themselves in URIs and in the certificates. If the certificate is accepted, the client has to again send the RTSP request. In that request, the client has to include the Accept-Credentials header including the hash over the DER-encoded certificate for all trusted proxies in the chain.
Example: C->P: SETUP rtsps://test.example.org/secret/audio RTSP/2.0 CSeq: 2 Transport: RTP/AVP;unicast;dest_addr="192.0.2.5:4588"/ "192.0.2.5:4589" Accept-Ranges: npt, smpte, clock Accept-Credentials: User P->C: RTSP/2.0 470 Connection Authorization Required CSeq: 2 Connection-Credentials: "rtsps://test.example.org"; MIIDNTCCAp... C->P: SETUP rtsps://test.example.org/secret/audio RTSP/2.0 CSeq: 3 Transport: RTP/AVP;unicast;dest_addr="192.0.2.5:4588"/ "192.0.2.5:4589" Accept-Credentials: User "rtsps://test.example.org";sha-256; dPYD7txpoGTbAqZZQJ+vaeOkyH4= Accept-Ranges: npt, smpte, clock P->S: SETUP rtsps://test.example.org/secret/audio RTSP/2.0 CSeq: 3 Transport: RTP/AVP;unicast;dest_addr="192.0.2.5:4588"/ "192.0.2.5:4589" Via: RTSP/2.0 proxy.example.org Accept-Credentials: User "rtsps://test.example.org";sha-256; dPYD7txpoGTbAqZZQJ+vaeOkyH4= Accept-Ranges: npt, smpte, clock One implication of this process is that the connection for secured RTSP messages may take significantly more round-trip times for the first message. A complete extra message exchange between the proxy connecting to the next hop and the client results because of the process for approval for each hop. However, if each message contains the chain of proxies that the requester accepts, the remaining message exchange should not be delayed. The procedure of including the credentials in each request rather than building state in each proxy avoids the need for revocation procedures.20. Syntax
The RTSP syntax is described in an Augmented Backus-Naur Form (ABNF) as defined in RFC 5234 [RFC5234]. It uses the basic definitions present in RFC 5234.
Please note that ABNF strings, e.g., "Accept", are case insensitive as specified in Section 2.3 of RFC 5234. The RTSP syntax makes use of the ISO 10646 character set in UTF-8 encoding [RFC3629].20.1. Base Syntax
RTSP header values can be folded onto multiple lines if the continuation line begins with a space or horizontal tab. All linear whitespace, including folding, has the same semantics as SP. A recipient MAY replace any linear whitespace with a single SP before interpreting the field-value or forwarding the message downstream. The SWS construct is used when linear whitespace is optional, generally between tokens and separators. To separate the header name from the rest of value, a colon is used, which, by the above rule, allows whitespace before, but no line break, and whitespace after, including a line break. The HCOLON defines this construct. OCTET = %x00-FF ; any 8-bit sequence of data CHAR = %x01-7F ; any US-ASCII character (octets 1 - 127) UPALPHA = %x41-5A ; any US-ASCII uppercase letter "A".."Z" LOALPHA = %x61-7A ; any US-ASCII lowercase letter "a".."z" ALPHA = UPALPHA / LOALPHA DIGIT = %x30-39 ; any US-ASCII digit "0".."9" CTL = %x00-1F / %x7F ; any US-ASCII control character ; (octets 0 - 31) and DEL (127) CR = %x0D ; US-ASCII CR, carriage return (13) LF = %x0A ; US-ASCII LF, linefeed (10) SP = %x20 ; US-ASCII SP, space (32) HT = %x09 ; US-ASCII HT, horizontal-tab (9) BACKSLASH = %x5C ; US-ASCII backslash (92) CRLF = CR LF LWS = [CRLF] 1*( SP / HT ) ; Line-breaking whitespace SWS = [LWS] ; Separating whitespace HCOLON = *( SP / HT ) ":" SWS TEXT = %x20-7E / %x80-FF ; any OCTET except CTLs tspecials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / BACKSLASH / DQUOTE / "/" / "[" / "]" / "?" / "=" / "{" / "}" / SP / HT token = 1*(%x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7A / %x7C / %x7E) ; 1*<any CHAR except CTLs or tspecials> quoted-string = ( DQUOTE *qdtext DQUOTE )
qdtext = %x20-21 / %x23-5B / %x5D-7E / quoted-pair / UTF8-NONASCII ; No DQUOTE and no "\" quoted-pair = "\\" / ( "\" DQUOTE ) ctext = %x20-27 / %x2A-7E / %x80-FF ; any OCTET except CTLs, "(" and ")" generic-param = token [ EQUAL gen-value ] gen-value = token / host / quoted-string safe = "$" / "-" / "_" / "." / "+" extra = "!" / "*" / "'" / "(" / ")" / "," rtsp-extra = "!" / "*" / "'" / "(" / ")" HEX = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" / "a" / "b" / "c" / "d" / "e" / "f" LHEX = DIGIT / "a" / "b" / "c" / "d" / "e" / "f" ; lowercase "a-f" Hex reserved = ";" / "/" / "?" / ":" / "@" / "&" / "=" unreserved = ALPHA / DIGIT / safe / extra rtsp-unreserved = ALPHA / DIGIT / safe / rtsp-extra base64 = *base64-unit [base64-pad] base64-unit = 4base64-char base64-pad = (2base64-char "==") / (3base64-char "=") base64-char = ALPHA / DIGIT / "+" / "/" SLASH = SWS "/" SWS ; slash EQUAL = SWS "=" SWS ; equal LPAREN = SWS "(" SWS ; left parenthesis RPAREN = SWS ")" SWS ; right parenthesis COMMA = SWS "," SWS ; comma SEMI = SWS ";" SWS ; semicolon COLON = SWS ":" SWS ; colon MINUS = SWS "-" SWS ; minus/dash LDQUOT = SWS DQUOTE ; open double quotation mark RDQUOT = DQUOTE SWS ; close double quotation mark RAQUOT = ">" SWS ; right angle quote LAQUOT = SWS "<" ; left angle quote TEXT-UTF8char = %x21-7E / UTF8-NONASCII UTF8-NONASCII = UTF8-2 / UTF8-3 / UTF8-4 UTF8-1 = <As defined in RFC 3629> UTF8-2 = <As defined in RFC 3629> UTF8-3 = <As defined in RFC 3629> UTF8-4 = <As defined in RFC 3629> UTF8-tail = <As defined in RFC 3629>
POS-FLOAT = 1*12DIGIT ["." 1*9DIGIT] FLOAT = ["-"] POS-FLOAT20.2. RTSP Protocol Definition
20.2.1. Generic Protocol Elements
RTSP-IRI = schemes ":" IRI-rest IRI-rest = ihier-part [ "?" iquery ] ihier-part = "//" iauthority ipath-abempty RTSP-IRI-ref = RTSP-IRI / irelative-ref irelative-ref = irelative-part [ "?" iquery ] irelative-part = "//" iauthority ipath-abempty / ipath-absolute / ipath-noscheme / ipath-empty iauthority = < As defined in RFC 3987> ipath = ipath-abempty ; begins with "/" or is empty / ipath-absolute ; begins with "/" but not "//" / ipath-noscheme ; begins with a non-colon segment / ipath-rootless ; begins with a segment / ipath-empty ; zero characters ipath-abempty = *( "/" isegment ) ipath-absolute = "/" [ isegment-nz *( "/" isegment ) ] ipath-noscheme = isegment-nz-nc *( "/" isegment ) ipath-rootless = isegment-nz *( "/" isegment ) ipath-empty = 0<ipchar> isegment = *ipchar [";" *ipchar] isegment-nz = 1*ipchar [";" *ipchar] / ";" *ipchar isegment-nz-nc = (1*ipchar-nc [";" *ipchar-nc]) / ";" *ipchar-nc ; non-zero-length segment without any colon ":" ; No parameter (; delimited) inside path. ipchar = iunreserved / pct-encoded / sub-delims / ":" / "@" ipchar-nc = iunreserved / pct-encoded / sub-delims / "@" ; sub-delims is different from RFC 3987 ; not including ";" iquery = < As defined in RFC 3987> iunreserved = < As defined in RFC 3987> pct-encoded = < As defined in RFC 3987>
RTSP-URI = schemes ":" URI-rest RTSP-REQ-URI = schemes ":" URI-req-rest RTSP-URI-Ref = RTSP-URI / RTSP-Relative RTSP-REQ-Ref = RTSP-REQ-URI / RTSP-REQ-Rel schemes = "rtsp" / "rtsps" / scheme scheme = < As defined in RFC 3986> URI-rest = hier-part [ "?" query ] URI-req-rest = hier-part [ "?" query ] ; Note fragment part not allowed in requests hier-part = "//" authority path-abempty RTSP-Relative = relative-part [ "?" query ] RTSP-REQ-Rel = relative-part [ "?" query ] relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty authority = < As defined in RFC 3986> query = < As defined in RFC 3986> path = path-abempty ; begins with "/" or is empty / path-absolute ; begins with "/" but not "//" / path-noscheme ; begins with a non-colon segment / path-rootless ; begins with a segment / path-empty ; zero characters path-abempty = *( "/" segment ) path-absolute = "/" [ segment-nz *( "/" segment ) ] path-noscheme = segment-nz-nc *( "/" segment ) path-rootless = segment-nz *( "/" segment ) path-empty = 0<pchar> segment = *pchar [";" *pchar] segment-nz = ( 1*pchar [";" *pchar]) / (";" *pchar) segment-nz-nc = ( 1*pchar-nc [";" *pchar-nc]) / (";" *pchar-nc) ; non-zero-length segment without any colon ":" ; No parameter (; delimited) inside path. pchar = unreserved / pct-encoded / sub-delims / ":" / "@" pchar-nc = unreserved / pct-encoded / sub-delims / "@" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "=" ; sub-delims is different from RFC 3986/3987 ; not including ";"
smpte-range = smpte-type [EQUAL smpte-range-spec] ; See section 4.4 smpte-range-spec = ( smpte-time "-" [ smpte-time ] ) / ( "-" smpte-time ) smpte-type = "smpte" / "smpte-30-drop" / "smpte-25" / smpte-type-extension ; other timecodes may be added smpte-type-extension = "smpte" token smpte-time = 1*2DIGIT ":" 1*2DIGIT ":" 1*2DIGIT [ ":" 1*2DIGIT [ "." 1*2DIGIT ] ] npt-range = "npt" [EQUAL npt-range-spec] npt-range-spec = ( npt-time "-" [ npt-time ] ) / ( "-" npt-time ) npt-time = "now" / npt-sec / npt-hhmmss / npt-hhmmss-comp npt-sec = 1*19DIGIT [ "." 1*9DIGIT ] npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." 1*9DIGIT ] npt-hh = 2*19DIGIT ; any positive number npt-mm = 2*2DIGIT ; 0-59 npt-ss = 2*2DIGIT ; 0-59 npt-hhmmss-comp = npt-hh-comp ":" npt-mm-comp ":" npt-ss-comp [ "." 1*9DIGIT ] ; Compatibility format npt-hh-comp = 1*19DIGIT ; any positive number npt-mm-comp = 1*2DIGIT ; 0-59 npt-ss-comp = 1*2DIGIT ; 0-59 utc-range = "clock" [EQUAL utc-range-spec] utc-range-spec = ( utc-time "-" [ utc-time ] ) / ( "-" utc-time ) utc-time = utc-date "T" utc-clock "Z" utc-date = 8DIGIT utc-clock = 6DIGIT [ "." 1*9DIGIT ] feature-tag = token session-id = 1*256( ALPHA / DIGIT / safe ) extension-header = header-name HCOLON header-value header-name = token header-value = *(TEXT-UTF8char / LWS)
20.2.2. Message Syntax
RTSP-message = Request / Response ; RTSP/2.0 messages Request = Request-Line *((general-header / request-header / message-body-header) CRLF) CRLF [ message-body-data ] Response = Status-Line *((general-header / response-header / message-body-header) CRLF) CRLF [ message-body-data ] Request-Line = Method SP Request-URI SP RTSP-Version CRLF Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF Method = "DESCRIBE" / "GET_PARAMETER" / "OPTIONS" / "PAUSE" / "PLAY" / "PLAY_NOTIFY" / "REDIRECT" / "SETUP" / "SET_PARAMETER" / "TEARDOWN" / extension-method extension-method = token Request-URI = "*" / RTSP-REQ-URI RTSP-Version = "RTSP/" 1*DIGIT "." 1*DIGIT message-body-data = 1*OCTET Status-Code = "100" ; Continue / "200" ; OK / "301" ; Moved Permanently / "302" ; Found / "303" ; See Other / "304" ; Not Modified / "305" ; Use Proxy
/ "400" ; Bad Request / "401" ; Unauthorized / "402" ; Payment Required / "403" ; Forbidden / "404" ; Not Found / "405" ; Method Not Allowed / "406" ; Not Acceptable / "407" ; Proxy Authentication Required / "408" ; Request Timeout / "410" ; Gone / "412" ; Precondition Failed / "413" ; Request Message Body Too Large / "414" ; Request-URI Too Long / "415" ; Unsupported Media Type / "451" ; Parameter Not Understood / "452" ; reserved / "453" ; Not Enough Bandwidth / "454" ; Session Not Found / "455" ; Method Not Valid In This State / "456" ; Header Field Not Valid for Resource / "457" ; Invalid Range / "458" ; Parameter Is Read-Only / "459" ; Aggregate Operation Not Allowed / "460" ; Only Aggregate Operation Allowed / "461" ; Unsupported Transport / "462" ; Destination Unreachable / "463" ; Destination Prohibited / "464" ; Data Transport Not Ready Yet / "465" ; Notification Reason Unknown / "466" ; Key Management Error / "470" ; Connection Authorization Required / "471" ; Connection Credentials Not Accepted / "472" ; Failure to Establish Secure Connection / "500" ; Internal Server Error / "501" ; Not Implemented / "502" ; Bad Gateway / "503" ; Service Unavailable / "504" ; Gateway Timeout / "505" ; RTSP Version Not Supported / "551" ; Option Not Supported / "553" ; Proxy Unavailable / extension-code extension-code = 3DIGIT Reason-Phrase = 1*(TEXT-UTF8char / HT / SP)
rtsp-header = general-header / request-header / response-header / message-body-header general-header = Accept-Ranges / Cache-Control / Connection / CSeq / Date / Media-Properties / Media-Range / Pipelined-Requests / Proxy-Supported / Range / RTP-Info / Scale / Seek-Style / Server / Session / Speed / Supported / Timestamp / Transport / User-Agent / Via / extension-header request-header = Accept / Accept-Credentials / Accept-Encoding / Accept-Language / Authorization / Bandwidth / Blocksize / From / If-Match / If-Modified-Since / If-None-Match / Notify-Reason / Proxy-Authorization / Proxy-Require / Referrer / Request-Status / Require / Terminate-Reason / extension-header
response-header = Authentication-Info / Connection-Credentials / Location / MTag / Proxy-Authenticate / Proxy-Authentication-Info / Public / Retry-After / Unsupported / WWW-Authenticate / extension-header message-body-header = Allow / Content-Base / Content-Encoding / Content-Language / Content-Length / Content-Location / Content-Type / Expires / Last-Modified / extension-header20.2.3. Header Syntax
Accept = "Accept" HCOLON [ accept-range *(COMMA accept-range) ] accept-range = media-type-range [SEMI accept-params] media-type-range = ( "*/*" / ( m-type SLASH "*" ) / ( m-type SLASH m-subtype ) ) *( SEMI m-parameter ) accept-params = "q" EQUAL qvalue *(SEMI generic-param ) qvalue = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3("0") ] ) Accept-Credentials = "Accept-Credentials" HCOLON cred-decision cred-decision = ("User" [LWS cred-info]) / "Proxy" / "Any" / (token [LWS 1*header-value]) ; For future extensions cred-info = cred-info-data *(COMMA cred-info-data) cred-info-data = DQUOTE RTSP-REQ-URI DQUOTE SEMI hash-alg SEMI base64 hash-alg = "sha-256" / extension-alg extension-alg = token Accept-Encoding = "Accept-Encoding" HCOLON
[ encoding *(COMMA encoding) ] encoding = codings [SEMI accept-params] codings = content-coding / "*" content-coding = "identity" / token Accept-Language = "Accept-Language" HCOLON language *(COMMA language) language = language-range [SEMI accept-params] language-range = language-tag / "*" language-tag = primary-tag *( "-" subtag ) primary-tag = 1*8ALPHA subtag = 1*8ALPHA Accept-Ranges = "Accept-Ranges" HCOLON acceptable-ranges acceptable-ranges = (range-unit *(COMMA range-unit)) range-unit = "npt" / "smpte" / "smpte-30-drop" / "smpte-25" / "clock" / extension-format extension-format = token Allow = "Allow" HCOLON Method *(COMMA Method) Authentication-Info = "Authentication-Info" HCOLON auth-param-list auth-param-list = <As the Authentication-Info element in RFC 7615> Authorization = "Authorization" HCOLON credentials credentials = <As defined by RFC 7235> Bandwidth = "Bandwidth" HCOLON 1*19DIGIT Blocksize = "Blocksize" HCOLON 1*9DIGIT Cache-Control = "Cache-Control" HCOLON cache-directive *(COMMA cache-directive) cache-directive = cache-rqst-directive / cache-rspns-directive cache-rqst-directive = "no-cache" / "max-stale" [EQUAL delta-seconds] / "min-fresh" EQUAL delta-seconds / "only-if-cached" / cache-extension cache-rspns-directive = "public" / "private" / "no-cache" / "no-transform" / "must-revalidate" / "proxy-revalidate" / "max-age" EQUAL delta-seconds / cache-extension cache-extension = token [EQUAL (token / quoted-string)] delta-seconds = 1*19DIGIT
Connection = "Connection" HCOLON connection-token *(COMMA connection-token) connection-token = "close" / token Connection-Credentials = "Connection-Credentials" HCOLON cred-chain cred-chain = DQUOTE RTSP-REQ-URI DQUOTE SEMI base64 Content-Base = "Content-Base" HCOLON RTSP-URI Content-Encoding = "Content-Encoding" HCOLON content-coding *(COMMA content-coding) Content-Language = "Content-Language" HCOLON language-tag *(COMMA language-tag) Content-Length = "Content-Length" HCOLON 1*19DIGIT Content-Location = "Content-Location" HCOLON RTSP-REQ-Ref Content-Type = "Content-Type" HCOLON media-type media-type = m-type SLASH m-subtype *(SEMI m-parameter) m-type = discrete-type / composite-type discrete-type = "text" / "image" / "audio" / "video" / "application" / extension-token composite-type = "message" / "multipart" / extension-token extension-token = ietf-token / x-token ietf-token = token x-token = "x-" token m-subtype = extension-token / iana-token iana-token = token m-parameter = m-attribute EQUAL m-value m-attribute = token m-value = token / quoted-string CSeq = "CSeq" HCOLON cseq-nr cseq-nr = 1*9DIGIT Date = "Date" HCOLON RTSP-date RTSP-date = date-time ; date-time = <As defined in RFC 5322> Expires = "Expires" HCOLON RTSP-date From = "From" HCOLON from-spec from-spec = ( name-addr / addr-spec ) *( SEMI from-param ) name-addr = [ display-name ] LAQUOT addr-spec RAQUOT addr-spec = RTSP-REQ-URI / absolute-URI absolute-URI = < As defined in RFC 3986> display-name = *(token LWS) / quoted-string from-param = tag-param / generic-param tag-param = "tag" EQUAL token If-Match = "If-Match" HCOLON ("*" / message-tag-list) message-tag-list = message-tag *(COMMA message-tag) message-tag = [ weak ] opaque-tag weak = "W/" opaque-tag = quoted-string
If-Modified-Since = "If-Modified-Since" HCOLON RTSP-date If-None-Match = "If-None-Match" HCOLON ("*" / message-tag-list) Last-Modified = "Last-Modified" HCOLON RTSP-date Location = "Location" HCOLON RTSP-REQ-URI Media-Properties = "Media-Properties" HCOLON [media-prop-list] media-prop-list = media-prop-value *(COMMA media-prop-value) media-prop-value = ("Random-Access" [EQUAL POS-FLOAT]) / "Beginning-Only" / "No-Seeking" / "Immutable" / "Dynamic" / "Time-Progressing" / "Unlimited" / ("Time-Limited" EQUAL utc-time) / ("Time-Duration" EQUAL POS-FLOAT) / ("Scales" EQUAL scale-value-list) / media-prop-ext media-prop-ext = token [EQUAL (1*rtsp-unreserved / quoted-string)] scale-value-list = DQUOTE scale-entry *(COMMA scale-entry) DQUOTE scale-entry = scale-value / (scale-value COLON scale-value) scale-value = FLOAT Media-Range = "Media-Range" HCOLON [ranges-list] ranges-list = ranges-spec *(COMMA ranges-spec) MTag = "MTag" HCOLON message-tag Notify-Reason = "Notify-Reason" HCOLON Notify-Reas-val Notify-Reas-val = "end-of-stream" / "media-properties-update" / "scale-change" / Notify-Reason-extension Notify-Reason-extension = token Pipelined-Requests = "Pipelined-Requests" HCOLON startup-id startup-id = 1*8DIGIT Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge-list challenge-list = <As defined by the WWW-Authenticate in RFC 7235> Proxy-Authentication-Info = "Proxy-Authentication-Info" HCOLON auth-param-list Proxy-Authorization = "Proxy-Authorization" HCOLON credentials Proxy-Require = "Proxy-Require" HCOLON feature-tag-list feature-tag-list = feature-tag *(COMMA feature-tag) Proxy-Supported = "Proxy-Supported" HCOLON [feature-tag-list] Public = "Public" HCOLON Method *(COMMA Method) Range = "Range" HCOLON ranges-spec ranges-spec = npt-range / utc-range / smpte-range / range-ext
range-ext = extension-format [EQUAL range-value] range-value = 1*(rtsp-unreserved / quoted-string / ":" ) Referrer = "Referrer" HCOLON (absolute-URI / RTSP-URI-Ref) Request-Status = "Request-Status" HCOLON req-status-info req-status-info = cseq-info LWS status-info LWS reason-info cseq-info = "cseq" EQUAL cseq-nr status-info = "status" EQUAL Status-Code reason-info = "reason" EQUAL DQUOTE Reason-Phrase DQUOTE Require = "Require" HCOLON feature-tag-list
RTP-Info = "RTP-Info" HCOLON [rtsp-info-spec *(COMMA rtsp-info-spec)] rtsp-info-spec = stream-url 1*ssrc-parameter stream-url = "url" EQUAL DQUOTE RTSP-REQ-Ref DQUOTE ssrc-parameter = LWS "ssrc" EQUAL ssrc HCOLON ri-parameter *(SEMI ri-parameter) ri-parameter = ("seq" EQUAL 1*5DIGIT) / ("rtptime" EQUAL 1*10DIGIT) / generic-param Retry-After = "Retry-After" HCOLON (RTSP-date / delta-seconds) Scale = "Scale" HCOLON scale-value Seek-Style = "Seek-Style" HCOLON Seek-S-values Seek-S-values = "RAP" / "CoRAP" / "First-Prior" / "Next" / Seek-S-value-ext Seek-S-value-ext = token Server = "Server" HCOLON ( product / comment ) *(LWS (product / comment)) product = token [SLASH product-version] product-version = token comment = LPAREN *( ctext / quoted-pair) RPAREN Session = "Session" HCOLON session-id [ SEMI "timeout" EQUAL delta-seconds ] Speed = "Speed" HCOLON lower-bound MINUS upper-bound lower-bound = POS-FLOAT upper-bound = POS-FLOAT Supported = "Supported" HCOLON [feature-tag-list]
Terminate-Reason = "Terminate-Reason" HCOLON TR-Info TR-Info = TR-Reason *(SEMI TR-Parameter) TR-Reason = "Session-Timeout" / "Server-Admin" / "Internal-Error" / token TR-Parameter = TR-time / TR-user-msg / generic-param TR-time = "time" EQUAL utc-time TR-user-msg = "user-msg" EQUAL quoted-string Timestamp = "Timestamp" HCOLON timestamp-value [LWS delay] timestamp-value = *19DIGIT [ "." *9DIGIT ] delay = *9DIGIT [ "." *9DIGIT ] Transport = "Transport" HCOLON transport-spec *(COMMA transport-spec) transport-spec = transport-id *trns-parameter transport-id = trans-id-rtp / other-trans trans-id-rtp = "RTP/" profile ["/" lower-transport] ; no LWS is allowed inside transport-id other-trans = token *("/" token)
profile = "AVP" / "SAVP" / "AVPF" / "SAVPF" / token lower-transport = "TCP" / "UDP" / token trns-parameter = (SEMI ( "unicast" / "multicast" )) / (SEMI "interleaved" EQUAL channel ["-" channel]) / (SEMI "ttl" EQUAL ttl) / (SEMI "layers" EQUAL 1*DIGIT) / (SEMI "ssrc" EQUAL ssrc *(SLASH ssrc)) / (SEMI "mode" EQUAL mode-spec) / (SEMI "dest_addr" EQUAL addr-list) / (SEMI "src_addr" EQUAL addr-list) / (SEMI "setup" EQUAL contrans-setup) / (SEMI "connection" EQUAL contrans-con) / (SEMI "RTCP-mux") / (SEMI "MIKEY" EQUAL MIKEY-Value) / (SEMI trn-param-ext) contrans-setup = "active" / "passive" / "actpass" contrans-con = "new" / "existing" trn-param-ext = par-name [EQUAL trn-par-value] par-name = token trn-par-value = *(rtsp-unreserved / quoted-string) ttl = 1*3DIGIT ; 0 to 255 ssrc = 8HEX channel = 1*3DIGIT ; 0 to 255 MIKEY-Value = base64 mode-spec = ( DQUOTE mode *(COMMA mode) DQUOTE ) mode = "PLAY" / token addr-list = quoted-addr *(SLASH quoted-addr) quoted-addr = DQUOTE (host-port / extension-addr) DQUOTE host-port = ( host [":" port] ) / ( ":" port ) extension-addr = 1*qdtext host = < As defined in RFC 3986> port = < As defined in RFC 3986>
Unsupported = "Unsupported" HCOLON feature-tag-list User-Agent = "User-Agent" HCOLON ( product / comment ) *(LWS (product / comment)) Via = "Via" HCOLON via-parm *(COMMA via-parm) via-parm = sent-protocol LWS sent-by *( SEMI via-params ) via-params = via-ttl / via-maddr / via-received / via-extension via-ttl = "ttl" EQUAL ttl via-maddr = "maddr" EQUAL host via-received = "received" EQUAL (IPv4address / IPv6address) IPv4address = < As defined in RFC 3986> IPv6address = < As defined in RFC 3986> via-extension = generic-param sent-protocol = protocol-name SLASH protocol-version SLASH transport-prot protocol-name = "RTSP" / token protocol-version = token transport-prot = "UDP" / "TCP" / "TLS" / other-transport other-transport = token sent-by = host [ COLON port ] WWW-Authenticate = "WWW-Authenticate" HCOLON challenge-list20.3. SDP Extension Syntax
This section defines in ABNF the SDP extensions defined for RTSP. See Appendix D for the definition of the extensions in text. control-attribute = "a=control:" *SP RTSP-REQ-Ref CRLF a-range-def = "a=range:" ranges-spec CRLF a-mtag-def = "a=mtag:" message-tag CRLF21. Security Considerations
The security considerations and threats around RTSP and its usage can be divided into considerations around the signaling protocol itself and the issues related to the media-stream delivery. However, when it comes to mitigation of security threats, a threat depending on the media-stream delivery may in fact be mitigated by a mechanism in the signaling protocol.
There are several chapters and an appendix in this document that define security solutions for the protocol. These sections will be referenced when discussing the threats below. However, the reader should take special notice of the Security Framework (Section 19) and the specification of how to use SRTP and its key-management (Appendix C.1.4) to achieve certain aspects of the media security.21.1. Signaling Protocol Threats
This section focuses on issues related to the signaling protocol. Because of the similarity in syntax and usage between RTSP servers and HTTP servers, the security considerations outlined in [RFC7230], [RFC7231], [RFC7232], [RFC7233], [RFC7234], and [RFC7235] apply as well. Specifically, please note the following: Abuse of Server Log Information: A server is in the position to save personal data about a user's requests that might identify their media consumption patterns or subjects of interest. This information is clearly confidential in nature, and its handling can be constrained by law in certain countries. Log information needs to be securely stored and appropriate guidelines followed for its analysis. See Section 9.8 of [RFC7230] for additional guidelines. Transfer of Sensitive Information: There is no reason to believe that information transferred in RTSP message, such as the URI and the content of headers, especially the Server, Via, Referrer, and From headers, may be any less sensitive than when used in HTTP. Therefore, all of the precautions regarding the protection of data privacy and user privacy apply to implementers of RTSP clients, servers, and proxies. See Sections 9.3-9.6 of [RFC7231] for further details. The RTSP methods defined in this document are primarily used to establish and control the delivery of the media data represented by the URI; thus, the RTSP message bodies are generally less sensitive than the ones in HTTP. Where HTTP bodies could contain, for example, your medical records, in RTSP, the sensitive video of your medical operation would be in the media stream over the media-transport protocol, not in the RTSP message. Still, one has to take note of what potential sensitive information is included in RTSP. The protection of the media data is separate, can be applied directly between client and server, and is dependent on the media-transport protocol in use. See Section 21.2 for further discussion. This possibility for separation of security between media-
resource content and the signaling protocol mitigates the risk of exposing the media content when using hop-by-hop security for RTSP signaling using proxies (Section 19.3). Attacks Based On File and Path Names: Though RTSP URIs are opaque handles that do not necessarily have file-system semantics, it is anticipated that many implementations will translate portions of the Request-URIs directly to file-system calls. In such cases, file systems SHOULD follow the precautions outlined in Section 9.1 of [RFC7231], such as checking for ".." in path components. Personal Information: RTSP clients are often privy to the same information that HTTP clients are (username, location, etc.) and thus should be equally sensitive. See Section 9.8 of [RFC7230], Sections 9.3-9.7 of [RFC7231], and Section 8 of [RFC7234] for further recommendations. Privacy Issues Connected to Accept Headers: Since similar usages of the "Accept" headers exist in RTSP as in HTTP, the same caveats outlined in Section 9.4 of [RFC7231] with regard to their use should be followed. Establishing Authority: RTSP shares with HTTP the question of how a client communicates with the authoritative source for media streams (Section 9.1 of [RFC7230]). The used DNS servers, the security of the communication, and any possibility of a man in the middle, and the trust in any RTSP proxies all affect the possibility that a client has received a non-authoritative response to a request. Ensuring that a client receives an authoritative response is challenging, although using the secure communication for RTSP signaling (rtsps) simplifies it significantly as the server can provide a hostname identity assertion in the TLS handshake. Location Headers and Spoofing: If a single server supports multiple organizations that do not trust each another, then it MUST check the values of the Content-Location header fields in responses that are generated under control of said organizations to make sure that they do not attempt to invalidate resources over which they have no authority (see Section 15.4 of [RFC2616]). In addition to the recommendations in the current HTTP specifications ([RFC7230], [RFC7231], [RFC7232], [RFC7233], [RFC7234], and [RFC7235] as of this writing) and also those of the previous relevant RFCs [RFC2068] [RFC2616], future HTTP specifications may provide additional guidance on security issues.
The following are added considerations for RTSP implementations. Session Hijacking: Since there is no or little relation between a transport-layer connection and an RTSP session, it is possible for a malicious client to issue requests with random session identifiers that could affect other clients of an unsuspecting server. To mitigate this, the server SHALL use a large, random and non-sequential session identifier to minimize the possibility of this kind of attack. However, unless the RTSP signaling is always confidentiality protected, e.g., using TLS, an on-path attacker will be able to hijack a session. Another choice for preventing session hijacking is to use client authentication and only allow the authenticated client creating the session to access that session. Authentication: Servers SHOULD implement both basic and Digest [RFC2617] authentication. In environments requiring tighter security for the control messages, the transport-layer mechanism TLS [RFC5246] SHOULD be used. Suspicious Behavior: Upon detecting instances of behavior that is deemed a security risk, RTSP servers SHOULD return error code 403 (Forbidden). RTSP servers SHOULD also be aware of attempts to probe the server for weaknesses and entry points and MAY arbitrarily disconnect and ignore further requests from clients that are deemed to be in violation of local security policy. TLS through Proxies: If one uses the possibility to connect TLS in multiple legs (Section 19.3), one really needs to be aware of the trust model. This procedure requires trust in all proxies part of the path to the server. The proxies one connects through are identified, assuming the proxies so far connected through are well behaved and fulfilling the trust. The accepted proxies are men in the middle and have access to all that goes on over the TLS connection. Thus, it is important to consider if that trust model is acceptable in the actual application. Further discussion of the actual trust model is in Section 19.3. It is important to note what difference in security properties, if any, may exist with the used media- transport protocol and its security mechanism. Using SRTP and the MIKEY-based key-establishment defined in Appendix C.1.4.1 enables media key-establishment to be done end-to-end without revealing the keys to the proxies.
Resource Exhaustion: As RTSP is a stateful protocol and establishes resource usage on the server, there is a clear possibility to attack the server by trying to overbook these resources to perform a DoS attack. This attack can be both against ongoing sessions and to prevent others from establishing sessions. RTSP agents will need to have mechanisms to prevent single peers from consuming extensive amounts of resources. The methods for guarding against this are varied and depend on the agent's role and capabilities and policies. Each implementation has to carefully consider its methods and policies to mitigate this threat. There are recommendations regarding the handling of connections in Section 10.7. The above threats and considerations have resulted in a set of security functions and mechanisms built into or used by the protocol. The signaling protocol relies on two security features defined in the Security Framework (Section 19): namely client authentication using HTTP authentication and TLS-based transport protection of the signaling messages. Both of these mechanisms are required to be implemented by any RTSP agent. A number of different security mitigations have been designed into the protocol and will be instantiated if the specification is implemented as written, for example, by ensuring sufficient amounts of entropy in the randomly generated session identifiers when not using client authentication to minimize the risk of session hijacking. When client authentication is used, protection against hijacking will be greatly improved by scoping the accessible sessions to the one this client identity has created. Some of the above threats are such that the implementation of the RTSP functionality itself needs to consider which policy and strategy it uses to mitigate them.