Files
Umbraco-CMS/src/Umbraco.Cms.Imaging.ImageSharp/ConfigureImageSharpMiddlewareOptions.cs
Ronald Barendse 27ae8bdba9 v12: Add HMAC image processing protection (#14181)
* Update to ImageSharp 2.1.0 and ImageSharp.Web 2.0.0-alpha.0.23

* Rename CachedNameLength to CacheHashLength and add CacheFolderDepth setting

* Replace PhysicalFileSystemProvider with WebRootImageProvider

* Support EXIF-orientation in image dimention extractor

* Remove virtual methods on FileProviderImageProvider

* Simplify FileInfoImageResolver

* Update to SixLabors.ImageSharp.Web 2.0.0-alpha.0.25 and remove custom providers

* Make CropWebProcessor EXIF orientation-aware

* Improve width/height sanitization

* Also use 'v' as cache buster value

* Add WebP to supported image file types

* Update to SixLabors.ImageSharp.Web 2.0.0-alpha.0.27 and fix test

* Fix rounding error and add test cases

* Update to newest and stable releases

* Move ImageSharpImageUrlGenerator to Umbraco.Web.Common

* Use IConfigureOptions to configure ImageSharp options

* Implement IEquatable on ImageUrlGenerationOptions classes

* Fix empty/null values in image URL generation and corresponding tests

* Use IsSupportedImageFormat extension method

* Remove unneeded reflection

* Add HMACSecretKey setting and add token when generating image URLs

* Ensure backoffice image URLs are generated by the server (and include a correct HMAC token)

* Abstract HMAC generation to IImageUrlTokenGenerator

* Change cache buster value to 'v' and use hexadecimal timestamp

* Update comments

* Fix backoffice thumbnail URL generation

* Update grid media thumbnail URL generation

* Remove breaking changes

* Strip unknown commands from image URL token

* Remove HMAC whitelisting possibility (not supported by ImageSharp)

* Update to SixLabors.ImageSharp 2.1.3

* Add comment to internal constructor

* Fix to support absolute image URLs

* Update to SixLabors.ImageSharp.Web 2.0.3-alpha.0.3

* Remove IImageUrlTokenGenerator and use ImageSharpRequestAuthorizationUtilities

* Move NuGet feed to config file

* Update to ImageSharp v3
2023-05-11 11:01:03 +02:00

90 lines
3.5 KiB
C#

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Headers;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using SixLabors.ImageSharp.Web.Commands;
using SixLabors.ImageSharp.Web.Middleware;
using SixLabors.ImageSharp.Web.Processors;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Imaging.ImageSharp;
/// <summary>
/// Configures the ImageSharp middleware options.
/// </summary>
/// <seealso cref="IConfigureOptions{ImageSharpMiddlewareOptions}" />
public sealed class ConfigureImageSharpMiddlewareOptions : IConfigureOptions<ImageSharpMiddlewareOptions>
{
private readonly Configuration _configuration;
private readonly ImagingSettings _imagingSettings;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigureImageSharpMiddlewareOptions" /> class.
/// </summary>
/// <param name="configuration">The ImageSharp configuration.</param>
/// <param name="imagingSettings">The Umbraco imaging settings.</param>
public ConfigureImageSharpMiddlewareOptions(Configuration configuration, IOptions<ImagingSettings> imagingSettings)
{
_configuration = configuration;
_imagingSettings = imagingSettings.Value;
}
/// <inheritdoc />
public void Configure(ImageSharpMiddlewareOptions options)
{
options.Configuration = _configuration;
options.HMACSecretKey = _imagingSettings.HMACSecretKey;
options.BrowserMaxAge = _imagingSettings.Cache.BrowserMaxAge;
options.CacheMaxAge = _imagingSettings.Cache.CacheMaxAge;
options.CacheHashLength = _imagingSettings.Cache.CacheHashLength;
// Use configurable maximum width and height
options.OnParseCommandsAsync = context =>
{
if (context.Commands.Count == 0 || _imagingSettings.HMACSecretKey.Length > 0)
{
// Nothing to parse or using HMAC authentication
return Task.CompletedTask;
}
int width = context.Parser.ParseValue<int>(context.Commands.GetValueOrDefault(ResizeWebProcessor.Width), context.Culture);
if (width <= 0 || width > _imagingSettings.Resize.MaxWidth)
{
context.Commands.Remove(ResizeWebProcessor.Width);
}
int height = context.Parser.ParseValue<int>(context.Commands.GetValueOrDefault(ResizeWebProcessor.Height), context.Culture);
if (height <= 0 || height > _imagingSettings.Resize.MaxHeight)
{
context.Commands.Remove(ResizeWebProcessor.Height);
}
return Task.CompletedTask;
};
// Change Cache-Control header when cache buster value is present
options.OnPrepareResponseAsync = context =>
{
if (context.Request.Query.ContainsKey("rnd") || context.Request.Query.ContainsKey("v"))
{
ResponseHeaders headers = context.Response.GetTypedHeaders();
CacheControlHeaderValue cacheControl = headers.CacheControl ?? new CacheControlHeaderValue()
{
Public = true
};
// ImageSharp enables cache revalidation by default, so disable and add immutable directive
cacheControl.MustRevalidate = false;
cacheControl.Extensions.Add(new NameValueHeaderValue("immutable"));
// Set updated value
headers.CacheControl = cacheControl;
}
return Task.CompletedTask;
};
}
}