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-header
20.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.