diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
index 5f15c4e0d..67875b3e6 100644
--- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
+++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs
@@ -328,6 +328,12 @@ namespace ImageProcessor.Web.HttpModules
string parts = !string.IsNullOrWhiteSpace(urlParameters) ? "?" + urlParameters : string.Empty;
string fullPath = string.Format("{0}{1}?{2}", requestPath, parts, queryString);
+ // Check whether the path is valid for other requests.
+ if (!isFileLocal && !currentService.IsValidRequest(requestPath + "?" + urlParameters))
+ {
+ return;
+ }
+
// Create a new cache to help process and cache the request.
DiskCache cache = new DiskCache(requestPath, fullPath, queryString);
string cachedPath = cache.CachedPath;
@@ -548,12 +554,7 @@ namespace ImageProcessor.Web.HttpModules
}
// Return the file based service
- if (ImageHelpers.IsValidImageExtension(path))
- {
- return services.FirstOrDefault(s => string.IsNullOrWhiteSpace(s.Prefix));
- }
-
- return null;
+ return services.FirstOrDefault(s => string.IsNullOrWhiteSpace(s.Prefix) && s.IsValidRequest(path));
}
#endregion
}
diff --git a/src/ImageProcessor.Web/Services/IImageService.cs b/src/ImageProcessor.Web/Services/IImageService.cs
index 3488f30cf..dfdcf0cdc 100644
--- a/src/ImageProcessor.Web/Services/IImageService.cs
+++ b/src/ImageProcessor.Web/Services/IImageService.cs
@@ -43,6 +43,17 @@ namespace ImageProcessor.Web.Services
///
Uri[] WhiteList { get; set; }
+ ///
+ /// Gets a value indicating whether the current request passes sanitizing rules.
+ ///
+ ///
+ /// The image path.
+ ///
+ ///
+ /// True if the request is valid; otherwise, False.
+ ///
+ bool IsValidRequest(string path);
+
///
/// Gets the image using the given identifier.
///
diff --git a/src/ImageProcessor.Web/Services/LocalFileImageService.cs b/src/ImageProcessor.Web/Services/LocalFileImageService.cs
index c9726b2eb..499753753 100644
--- a/src/ImageProcessor.Web/Services/LocalFileImageService.cs
+++ b/src/ImageProcessor.Web/Services/LocalFileImageService.cs
@@ -16,6 +16,8 @@ namespace ImageProcessor.Web.Services
using System.Threading.Tasks;
using System.Web;
+ using ImageProcessor.Web.Helpers;
+
///
/// The local file image service for retrieving images from the file system.
///
@@ -67,6 +69,20 @@ namespace ImageProcessor.Web.Services
///
public Uri[] WhiteList { get; set; }
+ ///
+ /// Gets a value indicating whether the current request passes sanitizing rules.
+ ///
+ ///
+ /// The image path.
+ ///
+ ///
+ /// True if the request is valid; otherwise, False.
+ ///
+ public bool IsValidRequest(string path)
+ {
+ return ImageHelpers.IsValidImageExtension(path);
+ }
+
///
/// Gets the image using the given identifier.
///
diff --git a/src/ImageProcessor.Web/Services/RemoteImageService.cs b/src/ImageProcessor.Web/Services/RemoteImageService.cs
index acebdf5d0..010beb413 100644
--- a/src/ImageProcessor.Web/Services/RemoteImageService.cs
+++ b/src/ImageProcessor.Web/Services/RemoteImageService.cs
@@ -14,7 +14,6 @@ namespace ImageProcessor.Web.Services
using System.Collections.Generic;
using System.IO;
using System.Net;
- using System.Security;
using System.Threading.Tasks;
using ImageProcessor.Web.Helpers;
@@ -84,6 +83,44 @@ namespace ImageProcessor.Web.Services
///
public Uri[] WhiteList { get; set; }
+ ///
+ /// Gets a value indicating whether the current request passes sanitizing rules.
+ ///
+ ///
+ /// The image path.
+ ///
+ ///
+ /// True if the request is valid; otherwise, False.
+ ///
+ public bool IsValidRequest(string path)
+ {
+ // Check the url is from a whitelisted location.
+ Uri url = new Uri(path);
+ string upper = url.Host.ToUpperInvariant();
+
+ // Check for root or sub domain.
+ bool validUrl = false;
+ foreach (Uri uri in this.WhiteList)
+ {
+ if (!uri.IsAbsoluteUri)
+ {
+ Uri rebaseUri = new Uri("http://" + uri.ToString().TrimStart(new[] { '.', '/' }));
+ validUrl = upper.StartsWith(rebaseUri.Host.ToUpperInvariant()) || upper.EndsWith(rebaseUri.Host.ToUpperInvariant());
+ }
+ else
+ {
+ validUrl = upper.StartsWith(uri.Host.ToUpperInvariant()) || upper.EndsWith(uri.Host.ToUpperInvariant());
+ }
+
+ if (validUrl)
+ {
+ break;
+ }
+ }
+
+ return validUrl;
+ }
+
///
/// Gets the image using the given identifier.
///
@@ -96,10 +133,6 @@ namespace ImageProcessor.Web.Services
public async Task GetImage(object id)
{
Uri uri = new Uri(id.ToString());
-
- // Check the url is from a whitelisted location.
- this.CheckSafeUrlLocation(uri);
-
RemoteFile remoteFile = new RemoteFile(uri)
{
MaxDownloadSize = int.Parse(this.Settings["MaxBytes"]),
@@ -132,41 +165,5 @@ namespace ImageProcessor.Web.Services
return buffer;
}
-
- ///
- /// Returns a value indicating whether the current url is in a list of safe download locations.
- ///
- ///
- /// The to check against.
- ///
- private void CheckSafeUrlLocation(Uri url)
- {
- string upper = url.Host.ToUpperInvariant();
-
- // Check for root or sub domain.
- bool validUrl = false;
- foreach (Uri uri in this.WhiteList)
- {
- if (!uri.IsAbsoluteUri)
- {
- Uri rebaseUri = new Uri("http://" + uri.ToString().TrimStart(new[] { '.', '/' }));
- validUrl = upper.StartsWith(rebaseUri.Host.ToUpperInvariant()) || upper.EndsWith(rebaseUri.Host.ToUpperInvariant());
- }
- else
- {
- validUrl = upper.StartsWith(uri.Host.ToUpperInvariant()) || upper.EndsWith(uri.Host.ToUpperInvariant());
- }
-
- if (validUrl)
- {
- break;
- }
- }
-
- if (!validUrl)
- {
- throw new SecurityException("Application is not configured to allow remote file downloads from this domain.");
- }
- }
}
}
diff --git a/src/TestWebsites/MVC/Web.config b/src/TestWebsites/MVC/Web.config
index 9bef44eaf..eb09cc6d7 100644
--- a/src/TestWebsites/MVC/Web.config
+++ b/src/TestWebsites/MVC/Web.config
@@ -27,7 +27,7 @@
-
+