fix additional legacy password formats (#12120)

* Added failing test to demo issue.

* Handle old machine key default.
This commit is contained in:
Paul Johnson
2022-03-10 13:59:19 +00:00
committed by Bjarke Berg
parent 8746d4c13d
commit 1ab0bb9254
2 changed files with 91 additions and 0 deletions

View File

@@ -209,11 +209,21 @@ namespace Umbraco.Cms.Core.Security
{
// This is for the v6-v8 hashing algorithm
if (algorithm.InvariantEquals(Constants.Security.AspNetUmbraco8PasswordHashAlgorithmName))
{
return true;
}
// Default validation value for old machine keys (switched to HMACSHA256 aspnet 4 https://docs.microsoft.com/en-us/aspnet/whitepapers/aspnet4/breaking-changes)
if (algorithm.InvariantEquals("SHA1"))
{
return true;
}
// This is for the <= v4 hashing algorithm
if (IsLegacySHA1Algorithm(algorithm))
{
return true;
}
return false;
}

View File

@@ -0,0 +1,81 @@
using AutoFixture.NUnit3;
using Microsoft.AspNetCore.Identity;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
{
[TestFixture]
public class UmbracoPasswordHasherTests
{
// Technically MD5, HMACSHA384 & HMACSHA512 were also possible but opt in as opposed to historic defaults.
[Test]
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "uB/pLEhhe1W7EtWMv/pSgg==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")] // Actually HMACSHA256
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")] // v4 site legacy password, with incorrect algorithm specified in database actually HMACSHA1 with password used as key.
[InlineAutoMoqData("SHA1", "Umbraco9Rocks!", "6tZGfG9NTxJJYp19Fac9og==zzRggqANxhb+CbD/VabEt8cIde8=")] // When SHA1 is set on machine key.
public void VerifyHashedPassword_WithValidLegacyPasswordHash_ReturnsSuccessRehashNeeded(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings{ HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.SuccessRehashNeeded, result);
}
[Test]
[InlineAutoMoqData("PBKDF2.ASPNETCORE.V3", "Umbraco9Rocks!", "AQAAAAEAACcQAAAAEDCrYcnIhHKr38yuchsDu6AFqqmLNvRooKObV25GC1LC1tLY+gWGU4xNug0lc17PHA==")]
public void VerifyHashedPassword_WithValidModernPasswordHash_ReturnsSuccess(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.Success, result);
}
[Test]
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "aB/cDeFaBcDefAbcD/EfaB==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")]
public void VerifyHashedPassword_WithIncorrectPassword_ReturnsFailed(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.Failed, result);
}
public class TestUserStub : UmbracoIdentityUser
{
public TestUserStub() => PasswordConfig = "not null or empty";
}
}
}