CVE-2024-39915: Insufficient Information (NVD-CWE-noinfo)
value: Thruk is a multibackend monitoring webinterface for Naemon, Nagios, Icinga and Shinken using the Livestatus API. This authenticated RCE in Thruk allows authorized users with network access to inject arbitrary commands via the URL parameter during PDF report generation. The Thruk web application does not properly process the url parameter when generating a PDF report. An authorized attacker with access to the reporting functionality could inject arbitrary commands that would be executed when the script /script/html2pdf.sh is called. The vulnerability can be exploited by an authorized user with network access. This issue has been addressed in version 3.16. Users are advised to upgrade. There are no known workarounds for this vulnerability.

CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-07-15T20:15Z
Repository: https://github.com/sni/Thruk
Language: Other
Files changed: Changes, plugins/plugins-available/reports2/lib/Thruk/Utils/Reports/Render.pm
Commit date: 2024-07-12 15:33:37 +0200
Commit message: fix using unescaped url in reports

skip spawing a shell when generating pdf report from custom url. Insufficient
escaping of the url lead to remote code execution vulnerability.

references:

- https://github.com/sni/Thruk/security/advisories/GHSA-r7gx-h738-4w6f

credits:

- https://github.com/OOsipova
- https://github.com/BlackFan (Kaspersky)

Diff: diff --git a/Changes b/Changes
index c3c1c447a..cc6841167 100644
--- a/Changes
+++ b/Changes
@@ -1,8 +1,9 @@
 This file documents the revision history for the Monitoring Webinterface Thruk.
 
 next:
+          - fix using unescaped url in reports
           - fix recurring downtimes crontab entry for 2nd/3rd days of month
           - fix sessions removed early when using kerberos authentication
           - fix using custom variables starting with multiple underlines
           - Rest:
             - add transformation and disaggregation functions
diff --git a/plugins/plugins-available/reports2/lib/Thruk/Utils/Reports/Render.pm b/plugins/plugins-available/reports2/lib/Thruk/Utils/Reports/Render.pm
index 550970f44..aca8a7d3f 100644
--- a/plugins/plugins-available/reports2/lib/Thruk/Utils/Reports/Render.pm
+++ b/plugins/plugins-available/reports2/lib/Thruk/Utils/Reports/Render.pm
@@ -389,13 +389,12 @@ sub get_url {
     push @{$c->stash->{'report_tmp_files_to_delete'}}, $c->stash->{'fake_session_file'};
 
     # directly convert external urls
     if($url =~ m/^https?:\/\/([^\/]+)/mx && $c->stash->{'param'}->{'pdf'} && $c->stash->{'param'}->{'pdf'} eq 'yes') {
         Thruk::Utils::External::update_status($ENV{'THRUK_JOB_DIR'}, 80, 'converting') if $ENV{'THRUK_JOB_DIR'};
-        my $cmd = $c->config->{home}.'/script/html2pdf.sh "'.$url.'" "'.$c->stash->{'attachment'}.'.pdf"';
         local $ENV{THRUK_SESSION_ID} = $sessionid;
-        Thruk::Utils::IO::cmd($cmd);
+        Thruk::Utils::IO::cmd($c, [$c->config->{home}.'/script/html2pdf.sh', $url, $c->stash->{'attachment'}.'.pdf']);
         move($c->stash->{'attachment'}.'.pdf', $c->stash->{'attachment'}) or die('move '.$c->stash->{'attachment'}.'.pdf to '.$c->stash->{'attachment'}.' failed: '.$!);
         $Thruk::Utils::PDF::ctype      = 'application/pdf';
         $Thruk::Utils::PDF::attachment = 'report.pdf';
         return "";
     }

Vulnerable code:         my $cmd = $c->config->{home}.'/script/html2pdf.sh "'.$url.'" "'.$c->stash->{'attachment'}.'.pdf"';
        Thruk::Utils::IO::cmd($cmd);
Fixed code:           - fix using unescaped url in reports
        Thruk::Utils::IO::cmd($c, [$c->config->{home}.'/script/html2pdf.sh', $url, $c->stash->{'attachment'}.'.pdf']);