diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
index c3d2ab8bb4..b04155137b 100644
--- a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
+++ b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
@@ -2349,6 +2349,12 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
Strict-Transport-Security, also known as the HSTS-header, was found.]]>
Strict-Transport-Security was not found.]]>
+
+ Strict-Transport-Security, also known as the HSTS-header, was found. This header should not be present on localhost.]]>
+
+
+ Strict-Transport-Security was not found. This header should not be present on localhost.]]>
+
X-XSS-Protection was found.]]>
X-XSS-Protection was not found.]]>
diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
index 6ddedc7797..4a025ed25c 100644
--- a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
+++ b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
@@ -2451,6 +2451,12 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
Strict-Transport-Security, also known as the HSTS-header, was found.]]>
Strict-Transport-Security was not found.]]>
+
+ Strict-Transport-Security, also known as the HSTS-header, was found. This header should not be present on localhost.]]>
+
+
+ Strict-Transport-Security was not found. This header should not be present on localhost.]]>
+
X-XSS-Protection was found.]]>
X-XSS-Protection was not found.]]>
diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs
index 229999472e..0637404045 100644
--- a/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs
+++ b/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs
@@ -3,6 +3,7 @@
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Core.HealthChecks.Checks.Security;
@@ -16,6 +17,11 @@ namespace Umbraco.Cms.Core.HealthChecks.Checks.Security;
Group = "Security")]
public class HstsCheck : BaseHttpHeaderCheck
{
+ private const string LocalizationPrefix = "hSTS";
+
+ private readonly IHostingEnvironment _hostingEnvironment;
+ private readonly ILocalizedTextService _textService;
+
///
/// Initializes a new instance of the class.
///
@@ -27,10 +33,56 @@ public class HstsCheck : BaseHttpHeaderCheck
/// but then you should include subdomains and I wouldn't suggest to do that for Umbraco-sites.
///
public HstsCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService)
- : base(hostingEnvironment, textService, "Strict-Transport-Security", "hSTS", true)
+ : base(hostingEnvironment, textService, "Strict-Transport-Security", LocalizationPrefix, true)
{
+ _hostingEnvironment = hostingEnvironment;
+ _textService = textService;
}
///
protected override string ReadMoreLink => Constants.HealthChecks.DocumentationLinks.Security.HstsCheck;
+
+ ///
+ public override async Task> GetStatus() =>
+ new HealthCheckStatus[] { await CheckForHeader() };
+
+ ///
+ /// The health check task.
+ ///
+ /// A with the result type reversed on localhost.
+ protected new async Task CheckForHeader()
+ {
+ HealthCheckStatus checkHeaderResult = await base.CheckForHeader();
+
+ var isLocalhost = _hostingEnvironment.ApplicationMainUrl?.Host.ToLowerInvariant() == "localhost";
+
+ // when not on localhost, the header should exist.
+ if (!isLocalhost)
+ {
+ return checkHeaderResult;
+ }
+
+ string message;
+ StatusResultType statusResultType;
+
+ // on localhost the header should not exist, so invert the status.
+ if (checkHeaderResult.ResultType == StatusResultType.Success)
+ {
+ statusResultType = StatusResultType.Error;
+
+ message = _textService.Localize("healthcheck", $"{LocalizationPrefix}CheckHeaderFoundOnLocalhost");
+ }
+ else
+ {
+ statusResultType = StatusResultType.Success;
+
+ message = _textService.Localize("healthcheck", $"{LocalizationPrefix}CheckHeaderNotFoundOnLocalhost");
+ }
+
+ return new HealthCheckStatus(message)
+ {
+ ResultType = statusResultType,
+ ReadMoreLink = ReadMoreLink,
+ };
+ }
}