Swap HSTS healthcheck status on localhost

This commit is contained in:
Jason Elkin
2022-10-11 01:41:50 +01:00
committed by Michael Latouche
parent 96da638236
commit 6cb53fd703
3 changed files with 65 additions and 1 deletions

View File

@@ -2347,6 +2347,12 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
<![CDATA[The header <strong>Strict-Transport-Security</strong>, also known as the HSTS-header, was found.]]></key>
<key alias="hSTSCheckHeaderNotFound">
<![CDATA[The header <strong>Strict-Transport-Security</strong> was not found.]]></key>
<key alias="hSTSCheckHeaderFoundOnLocalhost">
<![CDATA[The header <strong>Strict-Transport-Security</strong>, also known as the HSTS-header, was found. <strong>This header should not be present on localhost.</strong>]]>
</key>
<key alias="hSTSCheckHeaderNotFoundOnLocalhost">
<![CDATA[The header <strong>Strict-Transport-Security</strong> was not found. This header should not be present on localhost.]]>
</key>
<key alias="xssProtectionCheckHeaderFound"><![CDATA[The header <strong>X-XSS-Protection</strong> was found.]]></key>
<key alias="xssProtectionCheckHeaderNotFound">
<![CDATA[The header <strong>X-XSS-Protection</strong> was not found.]]></key>

View File

@@ -2450,6 +2450,12 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
<![CDATA[The header <strong>Strict-Transport-Security</strong>, also known as the HSTS-header, was found.]]></key>
<key alias="hSTSCheckHeaderNotFound">
<![CDATA[The header <strong>Strict-Transport-Security</strong> was not found.]]></key>
<key alias="hSTSCheckHeaderFoundOnLocalhost">
<![CDATA[The header <strong>Strict-Transport-Security</strong>, also known as the HSTS-header, was found. <strong>This header should not be present on localhost.</strong>]]>
</key>
<key alias="hSTSCheckHeaderNotFoundOnLocalhost">
<![CDATA[The header <strong>Strict-Transport-Security</strong> was not found. This header should not be present on localhost.]]>
</key>
<key alias="xssProtectionCheckHeaderFound"><![CDATA[The header <strong>X-XSS-Protection</strong> was found.]]></key>
<key alias="xssProtectionCheckHeaderNotFound">
<![CDATA[The header <strong>X-XSS-Protection</strong> was not found.]]></key>

View File

@@ -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;
/// <summary>
/// Initializes a new instance of the <see cref="HstsCheck" /> class.
/// </summary>
@@ -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.
/// </remarks>
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;
}
/// <inheritdoc />
protected override string ReadMoreLink => Constants.HealthChecks.DocumentationLinks.Security.HstsCheck;
/// <inheritdoc />
public override async Task<IEnumerable<HealthCheckStatus>> GetStatus() =>
new HealthCheckStatus[] { await CheckForHeader() };
/// <summary>
/// The health check task.
/// </summary>
/// <returns>A <see cref="Task{HealthCheckStatus}"/> with the result type reversed on localhost.</returns>
protected new async Task<HealthCheckStatus> 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,
};
}
}