← Commit list

b5c3349371

Joshua Rogers
Joshua Rogers
2026-09-17
SUCCESS Duration: 410s

Subject

rtsp: do not send a learned session id to another origin

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.md+2 -1
@@ -31,7 +31,8 @@ Session ID for the handle. Useful for resuming an in-progress session. Once
this value is set to any non-NULL value, libcurl returns
*CURLE_RTSP_SESSION_ERROR* if the ID received from the server does not match.
If unset (or set to NULL), libcurl automatically sets the ID the first time
-the server sets it in a response.
+the server sets it in a response. Such an ID is only sent back to the origin
+that issued it, unless CURLOPT_UNRESTRICTED_AUTH(3) is set.
The application does not have to keep the string around after setting this
option.
lib/rtsp.c+8 -0
@@ -41,6 +41,7 @@
#include "curlx/strdup.h"
#include "bufref.h"
#include "curlx/strparse.h"
+#include "peer.h"
/* meta key for storing protocol meta at easy handle */
#define CURL_META_RTSP_EASY "meta:proto:rtsp:easy"
@@ -457,6 +458,12 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
result = rtsp_setup_request(data, &block, rtspreq);
if(result)
goto out;
+
+ if(block.session_id && data->state.rtsp_session_origin &&
+ !data->set.allow_auth_to_other_hosts &&
+ !Curl_peer_equal(data->state.origin, data->state.rtsp_session_origin))
+ block.session_id = NULL;
+
/*
* Sanity check the custom headers
*/
@@ -1014,6 +1021,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
if(!mem ||
CURL_EASY_STR_SETN(data, STRING_RTSP_SESSION_ID, mem))
return CURLE_OUT_OF_MEMORY;
+ Curl_peer_link(&data->state.rtsp_session_origin, data->state.origin);
}
}
else if(checkprefix("Transport:", header)) {
lib/setopt.c+1 -0
@@ -2417,6 +2417,7 @@ static CURLcode setopt_cptr_misc(struct Curl_easy *data, CURLoption option,
return Curl_setstropt(data, STRING_SASL_AUTHZID, ptr);
#ifndef CURL_DISABLE_RTSP
case CURLOPT_RTSP_SESSION_ID:
+ Curl_peer_unlink(&data->state.rtsp_session_origin);
return Curl_setstropt(data, STRING_RTSP_SESSION_ID, ptr);
case CURLOPT_RTSP_STREAM_URI:
return Curl_setstropt(data, STRING_RTSP_STREAM_URI, ptr);
lib/url.c+3 -0
@@ -244,6 +244,9 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_ssl_close_all(data);
Curl_peer_unlink(&data->state.origin);
Curl_peer_unlink(&data->state.initial_origin);
+#ifndef CURL_DISABLE_RTSP
+ Curl_peer_unlink(&data->state.rtsp_session_origin);
+#endif
Curl_ssl_free_certinfo(data);
Curl_bufref_free(&data->state.referer);
lib/urldata.h+2 -0
@@ -620,6 +620,8 @@ struct UrlState {
#endif
#ifndef CURL_DISABLE_RTSP
/* This RTSP state information survives requests and connections */
+ struct Curl_peer *rtsp_session_origin; /* origin that issued the session id,
+ NULL when set by the application */
uint8_t rtp_channel_mask[32]; /* for the correctness checking of the
interleaved data */
uint32_t rtsp_next_client_CSeq; /* the session's next client CSeq */
tests/data/Makefile.am+1 -0
@@ -2096,6 +2096,7 @@ TESTCASES = \
test3230 \
test3231 \
test3232 \
+ test3233 \
\
test3300 \
test3301 \
tests/data/test3233+59 -0
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+RTSP
+SESSION_ID
+followlocation
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data1>
+RTSP/1.0 302 Found
+Server: RTSPD/libcurl-test
+CSeq: 1
+Session: SHOULD-NOT-LEAK
+Location: rtsp://example.com:%RTSPPORT/%TESTNUMBER
+Curl-private: swsbounce swsclose
+
+</data1>
+<data2>
+RTSP/1.0 200 OK
+Server: RTSPD/libcurl-test
+CSeq: 2
+Curl-private: swsclose
+
+</data2>
+</reply>
+
+# Client-Side
+<client>
+<server>
+rtsp
+</server>
+<tool>
+lib%TESTNUMBER
+</tool>
+
+<name>
+RTSP session id is not sent to another origin after a redirect
+</name>
+<command>
+rtsp://%HOSTIP:%RTSPPORT/%TESTNUMBER0001 example.com:%RTSPPORT:%HOSTIP
+</command>
+</client>
+
+<verify>
+<protocol crlf="headers">
+OPTIONS rtsp://%HOSTIP:%RTSPPORT/%TESTNUMBER0001 RTSP/1.0
+CSeq: 1
+
+OPTIONS rtsp://%HOSTIP:%RTSPPORT/%TESTNUMBER0001 RTSP/1.0
+CSeq: 2
+
+</protocol>
+</verify>
+
+</testcase>
tests/libtest/Makefile.inc+1 -0
@@ -333,6 +333,7 @@ TESTS_C = \
lib3207.c \
lib3208.c \
lib3231.c \
+ lib3233.c \
lib3595.c \
lib3596.c \
lib5000.c \
tests/libtest/lib3233.c+70 -0
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "first.h"
+
+/*
+ * A session id learned from one origin must not be sent to another one
+ * after a redirect.
+ */
+static CURLcode test_lib3233(const char *URL)
+{
+ CURLcode result;
+ CURL *curl;
+ struct curl_slist *resolve = NULL;
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ curl = curl_easy_init();
+ if(!curl) {
+ curl_mfprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ resolve = curl_slist_append(resolve, libtest_arg2);
+
+ easy_setopt(curl, CURLOPT_HEADERDATA, stdout);
+ easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ easy_setopt(curl, CURLOPT_URL, URL);
+ easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, URL);
+ easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
+ easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "rtsp");
+ easy_setopt(curl, CURLOPT_RESOLVE, resolve);
+
+ result = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_slist_free_all(resolve);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return result;
+}