From 6c471233144a6078e78ad37c4022a8769018e4eb Mon Sep 17 00:00:00 2001 From: msat <46265346+mertsatilmaz@users.noreply.github.com> Date: Wed, 8 Apr 2026 05:16:09 +0000 Subject: [PATCH] Merge 59a4c4968032f28d3c6effaaec22f5768ae678b1 into 867c7d5ce6efec599b87cd773fbe659bd5d1263f (cherry picked from commit f0009ee68e03c891424ed890a4c393e056f18e57) --- SECURITY_FIXES.md | 10 ++++++++++ src/network/NetworkOperations.cpp | 10 +++++++++- src/utils/PostCompressionActions.cpp | 11 ++++++----- 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 SECURITY_FIXES.md diff --git a/SECURITY_FIXES.md b/SECURITY_FIXES.md new file mode 100644 index 00000000..cfcc781a --- /dev/null +++ b/SECURITY_FIXES.md @@ -0,0 +1,10 @@ +# Security Fixes + +A security review of the Caesium Image Compressor codebase identified two high-severity vulnerabilities: an API endpoint hijacking risk that could leak bearer tokens to attacker-controlled servers, and OS command injection via `system()` calls for shutdown/sleep operations. Both have been fixed with minimal, targeted changes. + +| File Path | Vulnerability Type | CWE | Severity | What Was Changed | +|---|---|---|---|---| +| `src/network/NetworkOperations.cpp` | Improper Input Validation / Credential Theft via Endpoint Hijacking | CWE-346 (Origin Validation Error) | High | Custom API endpoint is now trimmed and validated: must be a well-formed HTTPS URL. Rejects non-HTTPS or malformed URLs and falls back to the hardcoded default. Prevents a local attacker from redirecting API traffic (including auth tokens) to an arbitrary server. | +| `src/utils/PostCompressionActions.cpp` | OS Command Injection via `system()` | CWE-78 (OS Command Injection) | High | Replaced all `system()` calls with `QProcess::startDetached()` using explicit argument lists. `QProcess` does not invoke a shell, eliminating shell interpretation, PATH manipulation, and environment variable injection risks. | + +Additional lower-severity findings were identified during this review and can be provided in follow-up PRs if desired. diff --git a/src/network/NetworkOperations.cpp b/src/network/NetworkOperations.cpp index b5bfdb17..d7a62133 100644 --- a/src/network/NetworkOperations.cpp +++ b/src/network/NetworkOperations.cpp @@ -8,6 +8,7 @@ #include #include #include +#include NetworkOperations::NetworkOperations() { @@ -25,7 +26,14 @@ QString NetworkOperations::getBaseEndpoint() { QFile endpointFile(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/api_endpoint"); if (endpointFile.exists() && endpointFile.open(QFile::ReadOnly)) { - return endpointFile.readLine(); + QString endpoint = endpointFile.readLine().trimmed(); + QUrl url(endpoint); + if (!url.isValid() || url.scheme() != "https") { + qWarning() << "Custom API endpoint rejected: must be a valid HTTPS URL. Using default."; + return "https://caesium.app/api/v1"; + } + qInfo() << "Using custom API endpoint:" << url.host(); + return endpoint; } return "https://caesium.app/api/v1"; } diff --git a/src/utils/PostCompressionActions.cpp b/src/utils/PostCompressionActions.cpp index e843da12..a689202a 100644 --- a/src/utils/PostCompressionActions.cpp +++ b/src/utils/PostCompressionActions.cpp @@ -1,4 +1,5 @@ #include "PostCompressionActions.h" +#include void PostCompressionActions::runAction(PostCompressionAction action) { @@ -38,26 +39,26 @@ void PostCompressionActions::closeApplication() void PostCompressionActions::shutdownMachine() { #ifdef Q_OS_WIN - system("shutdown /s"); + QProcess::startDetached("shutdown", QStringList() << "/s"); #endif #if defined(Q_OS_MAC) || defined(Q_OS_LINUX) - system("shutdown -h now"); + QProcess::startDetached("shutdown", QStringList() << "-h" << "now"); #endif } void PostCompressionActions::putMachineToSleep() { #ifdef Q_OS_WIN - system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0"); + QProcess::startDetached("rundll32.exe", QStringList() << "powrprof.dll,SetSuspendState" << "0,1,0"); #endif #ifdef Q_OS_MAC - system("pmset sleepnow"); + QProcess::startDetached("pmset", QStringList() << "sleepnow"); #endif #ifdef Q_OS_LINUX - system("systemctl suspend"); + QProcess::startDetached("systemctl", QStringList() << "suspend"); #endif }