From 03b2acdf43194413c719e5180c680bbd5e305011 Mon Sep 17 00:00:00 2001 From: djbadders <34887832+djbadders@users.noreply.github.com> Date: Wed, 17 Feb 2021 18:32:07 +0000 Subject: [PATCH] Security fix to avoid using the assets folder when creating zips --- Monitor/Pages/_get/DownloadFile.cshtml.cs | 26 +++++++++++++++++------ Monitor/Startup.cs | 10 ++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Monitor/Pages/_get/DownloadFile.cshtml.cs b/Monitor/Pages/_get/DownloadFile.cshtml.cs index 2d7cfed..900fa5a 100644 --- a/Monitor/Pages/_get/DownloadFile.cshtml.cs +++ b/Monitor/Pages/_get/DownloadFile.cshtml.cs @@ -1,5 +1,7 @@ -using System.Collections; -using Core.Main; +using System; +using System.Collections; +using System.IO; +using Microsoft.Net.Http.Headers; using Core.Helper; namespace Monitor.Pages { @@ -16,19 +18,29 @@ namespace Monitor.Pages { } } - private void InitializeDownload() { + private async void InitializeDownload() { + // Zip the file in an non web accessible folder string fileName = GetStringParameter("f", ""); + string tempFolder = PTMagicMonitorBasePath + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar; + if (System.IO.File.Exists(PTMagicBasePath + fileName)) { - if (!System.IO.Directory.Exists(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar)) { - System.IO.Directory.CreateDirectory(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar); + if (!System.IO.Directory.Exists(tempFolder)) { + System.IO.Directory.CreateDirectory(tempFolder); } string sourcefilePath = PTMagicBasePath + fileName; - string destinationFilePath = PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar + fileName + ".zip"; + string destinationFilePath = tempFolder + fileName + ".zip"; ZIPHelper.CreateZipFile(new ArrayList() { sourcefilePath }, destinationFilePath); - Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl + "assets/tmp/" + fileName + ".zip"); + // Write out the file + var data = System.IO.File.ReadAllBytes(destinationFilePath); + + Response.ContentType = "application/zip"; + Response.Headers[HeaderNames.CacheControl] = "no-cache"; + Response.Headers[HeaderNames.ContentDisposition] = String.Format("attachment; filename={0}", fileName); + await Response.BodyWriter.WriteAsync(new Memory(data)); + Response.BodyWriter.Complete(); } } } diff --git a/Monitor/Startup.cs b/Monitor/Startup.cs index b50797d..fa46e14 100644 --- a/Monitor/Startup.cs +++ b/Monitor/Startup.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Server.Kestrel.Core; using Core.Main; +using Core.Helper; using System.Runtime.InteropServices; using System.Diagnostics; @@ -58,6 +59,13 @@ namespace Monitor { options.AllowSynchronousIO = true; }); + + // Remove the old tmp folder if it exists + string oldTmpFolder = monitorBasePath + System.IO.Path.DirectorySeparatorChar + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar; + if (System.IO.Directory.Exists(oldTmpFolder)) + { + System.IO.Directory.Delete(oldTmpFolder, true); + } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -77,7 +85,7 @@ namespace Monitor // Configure request pipeline app.UseStaticFiles(); app.UseSession(); - app.UseMvcWithDefaultRoute(); + app.UseMvcWithDefaultRoute(); // Open the browser if (systemConfiguration.GeneralSettings.Monitor.OpenBrowserOnStart) OpenBrowser("http://localhost:" + systemConfiguration.GeneralSettings.Monitor.Port.ToString());