diff --git a/changelog.md b/changelog.md index 3369770f..f9016d1a 100644 --- a/changelog.md +++ b/changelog.md @@ -4,7 +4,8 @@ ### Features -- Server: Add secure RPC methods `AddStream` and `RemoveStream` (PR #1331, Issue #1330) +- Server: Add secure RPC method `Stream.AddStream` (PR #1331, Issue #1330) +- Server: Re-add RPC method `RemoveStream` (Issue #1330) ### Bugfixes diff --git a/doc/json_rpc_api/control.md b/doc/json_rpc_api/control.md index 8a4a0744..33e3f31e 100644 --- a/doc/json_rpc_api/control.md +++ b/doc/json_rpc_api/control.md @@ -484,8 +484,8 @@ See [Plugin.Stream.Player.SetProperty](stream_plugin.md#pluginstreamplayersetpro ### Stream.AddStream -Note: for security purposes, we don't allow adding `process` streams. -We also don't allow setting the `controlscript` query parameter of streamUri. +Note: For security purposes, the RPC interface allows only adding streams of these types: `pipe`, `file`, `tcp`, `alsa`, `jack` and `meta`. +It is also not allowed to set the `controlscript` query parameter of `streamUri`. #### Request @@ -513,7 +513,6 @@ We also don't allow setting the `controlscript` query parameter of streamUri. {"id":8,"jsonrpc":"2.0","result":{"stream_id":"stream 2"}} ``` - ##### Error ```json diff --git a/server/control_requests.cpp b/server/control_requests.cpp index df44f314..41610a83 100644 --- a/server/control_requests.cpp +++ b/server/control_requests.cpp @@ -690,21 +690,23 @@ void StreamAddRequest::execute(const jsonrpcpp::request_ptr& request, AuthInfo& checkParams(request, {"streamUri"}); - // Don't allow adding a process stream: CVE-2023-36177 - const std::string streamUri = request->params().get("streamUri"); - const StreamUri parsedUri(streamUri); - if (parsedUri.scheme == "process") - throw jsonrpcpp::InvalidParamsException("Adding process streams is not allowed", request->id()); + // Don't allow adding streams that start a user defined process: CVE-2023-36177 + static constexpr std::array whitelist{"pipe", "file", "tcp", "alsa", "jack", "meta"}; + const std::string stream_uri = request->params().get("streamUri"); + const StreamUri parsedUri(stream_uri); + + if (std::find(whitelist.begin(), whitelist.end(), parsedUri.scheme) == whitelist.end()) + throw jsonrpcpp::InvalidParamsException("Adding '" + parsedUri.scheme + "' streams is not allowed", request->id()); // Don't allow settings the controlscript streamUri property if (!parsedUri.getQuery("controlscript").empty()) - throw jsonrpcpp::InvalidParamsException("No controlscript streamUri property allowed", request->id()); + throw jsonrpcpp::InvalidParamsException("No 'controlscript' streamUri property allowed", request->id()); std::ignore = authinfo; LOG(INFO, LOG_TAG) << "Stream.AddStream(" << request->params().get("streamUri") << ")\n"; // Add stream - PcmStreamPtr stream = getStreamManager().addStream(streamUri); + PcmStreamPtr stream = getStreamManager().addStream(stream_uri); if (stream == nullptr) throw jsonrpcpp::InternalErrorException("Stream not created", request->id()); stream->start(); // We start the stream, otherwise it would be silent