CVE-2024-31221 (published 2024-04-08T15:15Z)

Sunshine is a self-hosted game stream host for Moonlight. Starting in version 0.10.0 and prior to version 0.23.0, after unpairing all devices in the web UI interface and then pairing only one device, all of the previously devices will be temporarily paired. Version 0.23.0 contains a patch for the issue. As a workaround, restarting Sunshine after unpairing all devices prevents the vulnerability.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/LizardByte/Sunshine
commit_details: repo_url: https://github.com/LizardByte/Sunshine
author: ReenigneArcher
author_date: 2024-04-06 16:39:16-04:00
msg: fix(security): ensure unpairing takes effect without restart (#2365)
repository: repo_url: https://github.com/LizardByte/Sunshine
repo_name: LizardByte/Sunshine
description: Self-hosted game stream host for Moonlight.
repo_language: C++
owner: LizardByte
file_changes: filename: crypto.cpp
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,10 @@ namespace crypto {
     X509_STORE_add_cert(x509_store.get(), cert.get());
     _certs.emplace_back(std::make_pair(std::move(cert), std::move(x509_store)));
   }
+  void
+  cert_chain_t::clear() {
+    _certs.clear();
+  }
 
   static int
   openssl_verify_cb(int ok, X509_STORE_CTX *ctx) {

programming_language: C++
filename: crypto.h
change_type: ModificationType.MODIFY
diff: @@ -73,6 +73,9 @@ namespace crypto {
     void
     add(x509_t &&cert);
 
+    void
+    clear();
+
     const char *
     verify(x509_t::element_type *cert);
 

programming_language: C++
filename: nvhttp.cpp
change_type: ModificationType.MODIFY
diff: @@ -42,6 +42,8 @@ namespace nvhttp {
   namespace fs = std::filesystem;
   namespace pt = boost::property_tree;
 
+  crypto::cert_chain_t cert_chain;
+
   class SunshineHttpsServer: public SimpleWeb::Server<SimpleWeb::HTTPS> {
   public:
     SunshineHttpsServer(const std::string &certification_file, const std::string &private_key_file):
@@ -1017,7 +1019,6 @@ namespace nvhttp {
     conf_intern.pkey = file_handler::read_file(config::nvhttp.pkey.c_str());
     conf_intern.servercert = file_handler::read_file(config::nvhttp.cert.c_str());
 
-    crypto::cert_chain_t cert_chain;
     for (auto &[_, client] : map_id_client) {
       for (auto &cert : client.certs) {
         cert_chain.add(crypto::x509(cert));
@@ -1026,15 +1027,15 @@ namespace nvhttp {
 
     auto add_cert = std::make_shared<safe::queue_t<crypto::x509_t>>(30);
 
-    // /resume doesn't always get the parameter "localAudioPlayMode"
-    // /launch will store it in host_audio
+    // resume doesn't always get the parameter "localAudioPlayMode"
+    // launch will store it in host_audio
     bool host_audio {};
 
     https_server_t https_server { config::nvhttp.cert, config::nvhttp.pkey };
     http_server_t http_server;
 
     // Verify certificates after establishing connection
-    https_server.verify = [&cert_chain, add_cert](SSL *ssl) {
+    https_server.verify = [add_cert](SSL *ssl) {
       crypto::x509_t x509 { SSL_get_peer_certificate(ssl) };
       if (!x509) {
         BOOST_LOG(info) << "unknown -- denied"sv;
@@ -1148,6 +1149,7 @@ namespace nvhttp {
   void
   erase_all_clients() {
     map_id_client.clear();
+    cert_chain.clear();
     save_state();
   }
 }  // namespace nvhttp

programming_language: C++