Updated security-sensitive Rust dependencies (#706)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-03-22 14:11:30 +01:00
1 parent cf6226546e
commit 309d36897e
5 files changed
+439 -240

No files matched your search

+382 -217
View File
File diff suppressed because it is too large. Load diff
+14 -12
View File
@@ -15,18 +15,17 @@ serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
keyring = { version = "3.6.2", features = ["apple-native", "windows-native", "sync-secret-service"] }
arboard = "3.6.1"
tokio = { version = "1.49.0", features = ["rt", "rt-multi-thread", "macros", "process"] }
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros", "process"] }
tokio-stream = "0.1.18"
futures = "0.3.31"
futures = "0.3.32"
async-stream = "0.3.6"
flexi_logger = "0.31.8"
log = { version = "0.4.29", features = ["kv"] }
once_cell = "1.21.3"
once_cell = "1.21.4"
rocket = { version = "0.5.1", features = ["json", "tls"] }
rand = "0.9.1"
rand_chacha = "0.9"
rand = "0.10.0"
rand_chacha = "0.10.0"
base64 = "0.22.1"
cipher = { version = "0.4.4", features = ["std"] }
aes = "0.8.4"
cbc = "0.1.2"
pbkdf2 = "0.12.2"
@@ -34,25 +33,28 @@ hmac = "0.12.1"
sha2 = "0.10.8"
rcgen = { version = "0.14.7", features = ["pem"] }
file-format = "0.28.0"
calamine = "0.33.0"
calamine = "0.34.0"
pdfium-render = "0.8.37"
sys-locale = "0.3.2"
cfg-if = "1.0.4"
pptx-to-md = "0.4.0"
tempfile = "3.8"
strum_macros = "0.27"
sysinfo = "0.38.0"
tempfile = "3.27.0"
strum_macros = "0.28.0"
sysinfo = "0.38.4"
# Fixes security vulnerability downstream, where the upstream is not fixed yet:
time = "0.3.47" # -> Rocket
bytes = "1.11.1" # -> almost every dependency
aws-lc-rs = "1.16.2" # -> reqwest
tar = "0.4.45" # -> Tauri v1
rustls-webpki = "0.103.10" # -> tokio, reqwest
[target.'cfg(target_os = "linux")'.dependencies]
# See issue https://github.com/tauri-apps/tauri/issues/4470
reqwest = { version = "0.13.1", features = ["native-tls-vendored"] }
reqwest = { version = "0.13.2", features = ["native-tls-vendored"] }
# Fixes security vulnerability downstream, where the upstream is not fixed yet:
openssl = "0.10.75"
openssl = "0.10.76" # -> reqwest, Tauri v1
[target.'cfg(target_os = "windows")'.dependencies]
windows-registry = "0.6.1"
+13 -2
View File
@@ -1,4 +1,6 @@
use rand::{RngCore, SeedableRng};
use log::error;
use rand::rngs::SysRng;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaChaRng;
/// The API token data structure used to authenticate requests.
@@ -36,7 +38,16 @@ impl APIToken {
pub fn generate_api_token() -> APIToken {
let mut token = [0u8; 32];
let mut rng = ChaChaRng::from_os_rng();
// The API token authenticates privileged runtime requests. If the OS-backed
// RNG cannot provide a secure seed, we abort instead of using a weaker RNG
// because a predictable token would silently break the app's security model.
let mut sys_rng = SysRng;
let mut rng = ChaChaRng::try_from_rng(&mut sys_rng)
.unwrap_or_else(|e| {
error!(Source = "API Token"; "Failed to seed ChaChaRng from SysRng: {e}");
panic!("Failed to seed ChaChaRng from SysRng: {e}");
});
rng.fill_bytes(&mut token);
APIToken::from_bytes(token.to_vec())
}
+28 -9
View File
@@ -4,10 +4,11 @@ use base64::Engine;
use base64::prelude::BASE64_STANDARD;
use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
use hmac::Hmac;
use log::info;
use log::{error, info};
use once_cell::sync::Lazy;
use pbkdf2::pbkdf2;
use rand::{RngCore, SeedableRng};
use rand::rngs::SysRng;
use rand::{Rng, SeedableRng};
use rocket::{data, Data, Request};
use rocket::data::ToByteUnit;
use rocket::http::Status;
@@ -31,15 +32,25 @@ pub static ENCRYPTION: Lazy<Encryption> = Lazy::new(|| {
// We use a cryptographically secure pseudo-random number generator
// to generate the secret password & salt. ChaCha20Rng is the algorithm
// of our choice:
let mut rng = rand_chacha::ChaChaRng::from_os_rng();
// of our choice. If the OS-backed RNG is unavailable, we fail fast instead
// of falling back to a weaker RNG because these values protect the IPC
// channel and must remain cryptographically secure.
let mut sys_rng = SysRng;
let mut rng = rand_chacha::ChaChaRng::try_from_rng(&mut sys_rng)
.unwrap_or_else(|e| {
error!(Source = "Encryption"; "Failed to seed ChaChaRng from SysRng: {e}");
panic!("Failed to seed ChaChaRng from SysRng: {e}");
});
// Fill the secret key & salt with random bytes:
rng.fill_bytes(&mut secret_key);
rng.fill_bytes(&mut secret_key_salt);
info!("Secret password for the IPC channel was generated successfully.");
Encryption::new(&secret_key, &secret_key_salt).unwrap()
Encryption::new(&secret_key, &secret_key_salt).unwrap_or_else(|e| {
error!(Source = "Encryption"; "Failed to initialize encryption for the IPC channel: {e}");
panic!("Failed to initialize encryption for the IPC channel: {e}");
})
});
/// The encryption struct used for the IPC channel.
@@ -98,9 +109,14 @@ impl Encryption {
/// Encrypts the given data.
pub fn encrypt(&self, data: &str) -> Result<EncryptedText, String> {
let cipher = Aes256CbcEnc::new(&self.key.into(), &self.iv.into());
let encrypted = cipher.encrypt_padded_vec_mut::<Pkcs7>(data.as_bytes());
let data = data.as_bytes();
let mut buffer = vec![0u8; data.len() + 16];
buffer[..data.len()].copy_from_slice(data);
let encrypted = cipher
.encrypt_padded_mut::<Pkcs7>(&mut buffer, data.len())
.map_err(|e| format!("Error encrypting data: {e}"))?;
let mut result = BASE64_STANDARD.encode(self.secret_key_salt);
result.push_str(&BASE64_STANDARD.encode(&encrypted));
result.push_str(&BASE64_STANDARD.encode(encrypted));
Ok(EncryptedText::new(result))
}
@@ -118,9 +134,12 @@ impl Encryption {
}
let cipher = Aes256CbcDec::new(&self.key.into(), &self.iv.into());
let decrypted = cipher.decrypt_padded_vec_mut::<Pkcs7>(encrypted).map_err(|e| format!("Error decrypting data: {e}"))?;
let mut buffer = encrypted.to_vec();
let decrypted = cipher
.decrypt_padded_mut::<Pkcs7>(&mut buffer)
.map_err(|e| format!("Error decrypting data: {e}"))?;
String::from_utf8(decrypted).map_err(|e| format!("Error converting decrypted data to string: {}", e))
String::from_utf8(decrypted.to_vec()).map_err(|e| format!("Error converting decrypted data to string: {}", e))
}
}