Unverified Commit 3ac27b27 authored by Moraxyc's avatar Moraxyc
Browse files

clash-verge-rev: apply patches for security problems



Co-Authored-By: default avatarwxt <3264117476@qq.com>
parent d99c55d7
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
From fff6494e26edce6bf8a5b4c40d9535f820608cc3 Mon Sep 17 00:00:00 2001
From: Moraxyc <i@qaq.li>
Date: Mon, 28 Apr 2025 16:43:29 +0800
Subject: [PATCH 1/2] core: validate bin_path to prevent RCE in start_clash

Add a security check in CoreManager::start_clash to ensure that the provided
binary path (`bin_path`) must be located under the current executable's
directory. This prevents potential remote code execution (RCE) attacks
caused by arbitrary binary path injection.
---
 src/service/core.rs | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/service/core.rs b/src/service/core.rs
index 84407a5..51081ed 100644
--- a/src/service/core.rs
+++ b/src/service/core.rs
@@ -7,6 +7,7 @@ use once_cell::sync::Lazy;
 use std::{
     collections::HashMap,
     sync::{atomic::Ordering, Arc, Mutex},
+    env,
 };
 
 impl CoreManager {
@@ -227,7 +228,7 @@ impl CoreManager {
             .unwrap()
             .running_pid
             .load(Ordering::Relaxed) as u32;
-        
+
         match process::find_processes("verge-mihomo") {
             Ok(pids) => {
                 // 直接在迭代过程中过滤和终止
@@ -248,18 +249,32 @@ impl CoreManager {
                     })
                     .filter(|&success| success)
                     .count();
-                    
+
                 println!("Successfully stopped {} verge-mihomo processes", kill_count);
             }
             Err(e) => {
                 eprintln!("Error finding verge-mihomo processes: {}", e);
             }
         }
-        
+
         Ok(())
     }
 
     pub fn start_clash(&self, body: StartBody) -> Result<(), String> {
+        {
+            let bin_path = std::path::Path::new(body.bin_path.as_str());
+            let current_exe = std::env::current_exe()
+                .map_err(|e| format!("Failed to get current exe path: {}", e))?;
+            let current_dir = current_exe.parent()
+                .ok_or("Failed to get current directory")?;
+
+            if !bin_path.starts_with(current_dir) {
+                return Err(format!(
+                    "Invalid binary path for clash kernel. It must be under: {}",
+                    current_dir.display()
+                ));
+            }
+        }
         {
             // Check clash & stop if needed
             let is_running_clash = self
-- 
2.49.0
+33 −0
Original line number Diff line number Diff line
From b104778a608862789f2be400b9f13a92b1ec5b20 Mon Sep 17 00:00:00 2001
From: Moraxyc <i@qaq.li>
Date: Mon, 28 Apr 2025 21:38:02 +0800
Subject: [PATCH 2/2] core: prevent overwriting existing file by validating its
 existence

Add a check to verify whether the specified `log_file` already exists before proceeding.
If the file exists, return an error to prevent accidental or malicious overwriting of files.
This enhances the security of log file handling by mitigating arbitrary file overwrite risks.
---
 src/service/core.rs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/service/core.rs b/src/service/core.rs
index 51081ed..a2c4f82 100644
--- a/src/service/core.rs
+++ b/src/service/core.rs
@@ -275,6 +275,12 @@ impl CoreManager {
                 ));
             }
         }
+        {
+            let log_file = std::path::Path::new(body.log_file.as_str());
+            if log_file.exists() {
+                return Err(format!("Log file already exists: {}", log_file.display()));
+            }
+        }
         {
             // Check clash & stop if needed
             let is_running_clash = self
-- 
2.49.0
+1 −4
Original line number Diff line number Diff line
@@ -80,9 +80,6 @@ let
      bot-wxt1221
    ];
    platforms = lib.platforms.linux;
    knownVulnerabilities = [
      "https://github.com/clash-verge-rev/clash-verge-rev/issues/3428"
    ];
  };
in
stdenv.mkDerivation {
@@ -118,7 +115,7 @@ stdenv.mkDerivation {
    cp -r ${unwrapped}/share/* $out/share
    cp -r ${unwrapped}/bin/clash-verge $out/bin/clash-verge
    # This can't be symbol linked. It will find mihomo in its runtime path
    ln -s ${service}/bin/clash-verge-service $out/bin/clash-verge-service
    cp ${service}/bin/clash-verge-service $out/bin/clash-verge-service
    ln -s ${mihomo}/bin/mihomo $out/bin/verge-mihomo
    # people who want to use alpha build show override mihomo themselves. The alpha core entry was removed in clash-verge.
    ln -s ${v2ray-geoip}/share/v2ray/geoip.dat $out/lib/Clash\ Verge/resources/geoip.dat
+13 −0
Original line number Diff line number Diff line
@@ -15,6 +15,19 @@ rustPlatform.buildRustPackage {
  src = src-service;
  sourceRoot = "${src-service.name}";

  patches = [
    # FIXME: remove until upstream fix these
    # https://github.com/clash-verge-rev/clash-verge-rev/issues/3428

    # Patch: Restrict bin_path in spawn_process to be under the clash-verge-service directory.
    # This prevents arbitrary code execution by ensuring only trusted binaries from the Nix store are allowed to run.
    ./0001-core-validate-bin_path-to-prevent-RCE-in-start_clash.patch

    # Patch: Add validation to prevent overwriting existing files.
    # This mitigates arbitrary file overwrite risks by ensuring a file does not already exist before writing.
    ./0002-core-prevent-overwriting-existing-file-by-validating.patch
  ];

  nativeBuildInputs = [
    pkg-config
  ];
+6 −0
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ rustPlatform.buildRustPackage {
    mv tauri.linux.conf.json.2 tauri.linux.conf.json
    chmod 777 ../.cargo
    rm ../.cargo/config.toml

    # As a side effect of patching the service to fix the arbitrary file overwrite issue,
    # we also need to update the timestamp format in the filename to the second level.
    # This ensures that the Clash kernel can still be restarted within one minute without problems.
    substituteInPlace src/utils/dirs.rs \
      --replace-fail '%Y-%m-%d-%H%M' '%Y-%m-%d-%H%M%S'
  '';

  nativeBuildInputs = [