CVE-2016-7838 (published 2017-06-09T16:29Z)

Untrusted search path vulnerability in WinSparkle versions prior to 0.5.3 allows remote attackers to execute arbitrary code via a specially crafted executable file in an unspecified directory.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-426
cwe_name: Untrusted Search Path
description: The product searches for critical resources using an externally-supplied search path that can point to resources that are not under the product's direct control.
extended_description: 
            This might allow attackers to execute their own programs, access unauthorized data files, or modify configuration in unexpected ways. If the product uses a search path to locate critical resources such as programs, then an attacker could modify that search path to point to a malicious program, which the targeted product would then execute. The problem extends to any type of critical resource that the product trusts.
            Some of the most common variants of untrusted search path are:
               
                  In various UNIX and Linux-based systems, the PATH environment variable may be consulted to locate executable programs, and LD_PRELOAD may be used to locate a separate library.
                  In various Microsoft-based systems, the PATH environment variable is consulted to locate a DLL, if the DLL is not found in other paths that appear earlier in the search order.
               
         
         

Fix information:
repo_url: https://github.com/vslavik/winsparkle
commit_details: repo_url: https://github.com/vslavik/winsparkle
author: Václav Slavík
author_date: 2016-12-12 18:32:14+01:00
msg: Verify UpdateTempDir isn't maliciously modified

Don't just delete the stored updates temporary directory on launch, but
validate the registry key to ensure it is in an expected location and
follows WinSparkle's naming convention. This is to prevent malicious
users from modifying this registry key and forcing the host app to
delete arbitrary directories (a user being able to delete the key would
be able to delete the directory themselves, so it's not a serious issue,
but it nevertheless is bad behavior and shouldn't be possible).
repository: repo_url: https://github.com/vslavik/winsparkle
repo_name: vslavik/winsparkle
description: App update framework for Windows, inspired by Sparkle for macOS
repo_language: C++
owner: vslavik
file_changes: filename: updatedownloader.cpp
change_type: ModificationType.MODIFY
diff: @@ -45,6 +45,17 @@ namespace winsparkle
 namespace
 {
 
+std::wstring GetUniqueTempDirectoryPrefix()
+{
+    wchar_t tmpdir[MAX_PATH + 1];
+    if (GetTempPath(MAX_PATH + 1, tmpdir) == 0)
+        throw Win32Exception("Cannot create temporary directory");
+
+    std::wstring dir(tmpdir);
+    dir += L"Update-";
+    return dir;
+}
+
 std::wstring CreateUniqueTempDirectory()
 {
     // We need to put downloaded updates into a directory of their own, because
@@ -53,15 +64,11 @@ std::wstring CreateUniqueTempDirectory()
     //
     // This code creates a new randomized directory name and tries to create it;
     // this process is repeated if the directory already exists.
-    wchar_t tmpdir[MAX_PATH+1];
-    if ( GetTempPath(MAX_PATH+1, tmpdir) == 0 )
-        throw Win32Exception("Cannot create temporary directory");
+    const std::wstring tmpdir = GetUniqueTempDirectoryPrefix();
 
     for ( ;; )
     {
         std::wstring dir(tmpdir);
-        dir += L"Update-";
-
         UUID uuid;
         UuidCreate(&uuid);
         RPC_WSTR uuidStr;
@@ -192,6 +199,21 @@ void UpdateDownloader::CleanLeftovers()
     if ( !Settings::ReadConfigValue("UpdateTempDir", tmpdir) )
         return;
 
+    // Check that the directory actually is a valid update temp dir, to prevent
+    // malicious users from forcing us into deleting arbitrary directories:
+    try
+    {
+        if (tmpdir.find(GetUniqueTempDirectoryPrefix()) != 0)
+        {
+            Settings::DeleteConfigValue("UpdateTempDir");
+            return;
+        }
+    }
+    catch (Win32Exception&) // cannot determine temp directory
+    {
+        return;
+    }
+
     tmpdir.append(1, '\0'); // double NULL-terminate for SHFileOperation
 
     SHFILEOPSTRUCT fos = {0};

programming_language: C++