From 794ca0f651fb2f2b3e3f6092e0f235506085e5de Mon Sep 17 00:00:00 2001 From: iliajie Date: Sat, 20 May 2023 12:05:03 +0300 Subject: [PATCH] Add ability to read potentially dangerous files safely or force download --- updown/fetch.cgi | 64 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/updown/fetch.cgi b/updown/fetch.cgi index b17bf2588..0c42790cc 100755 --- a/updown/fetch.cgi +++ b/updown/fetch.cgi @@ -80,14 +80,65 @@ if ($ENV{'PATH_INFO'}) { if (!$fetch_show) { print "Content-Disposition: Attachment\n"; } - @st = stat($file); - print "Content-length: $st[7]\n"; - print "X-Content-Type-Options: nosniff\n"; - print "Content-type: $type\n\n"; - while(read(FILE, $buffer, &get_buffer_size_binary())) { - print("$buffer"); + # Stat file + my @st = stat($file); + my $fsize = $st[7]; + + # Get and analyze the file contents first + my $fdata = ""; + my $dangertypes = $type =~ /html|xml|pdf/i; + my $htmltype = $type =~ /html/i ? 1 : 0; + my $pdftype = $type =~ /pdf/i ? 'pdf' : 0; + my $bsize = + $dangertypes ? $fsize : &get_buffer_size_binary(); + while(read(FILE, $buffer, $bsize)) { + if ($dangertypes) { + my $buffer_filtered = &filter_javascript($buffer, $pdftype); + # If content was changed upon filtering + if ($buffer_filtered ne $buffer) { + # For text simply return filtered but + # tell user that it was filtered out + if ($htmltype) { + # Add a banner showing content was changed + my $prefdata = + &ui_alert_box($text{'ui_jsblocked'}, 'danger'); + # Pass filtered content with the banner + # Insert the banner in HTML body + if ($buffer_filtered =~ s/()/$1$prefdata/) { + $fdata = $buffer_filtered; + } + else { + # Insert the banner to the top of HTML doc + $fdata = "$prefdata$buffer_filtered"; + } + # Update content length + $fsize = length($fdata); + } + # For no text files simply force + # download if file was altered + else { + # Force send it + $type = "application/octet-stream"; + print "Content-Disposition: Attachment\n"; + # Pass original content + $fdata = $buffer; + } + } + # Buffere was not changed, just pass it as is + else { + $fdata = $buffer; + } + } + else { + $fdata .= $buffer; + } } close(FILE); + + print "Content-length: $fsize\n"; + print "X-Content-Type-Options: nosniff\n"; + print "Content-type: $type\n\n"; + print "$fdata"; } # Switch back to root @@ -119,3 +170,4 @@ else { &redirect("fetch.cgi".$file); } } +