mirror of
https://github.com/bitwarden/mobile.git
synced 2025-02-16 01:11:25 +01:00
[PM-5731] feat: add incomplete rpId verification
This commit is contained in:
parent
ad8faec200
commit
0f5df0f6b0
37
src/Core/Utilities/Fido2/Fido2DomainUtils.cs
Normal file
37
src/Core/Utilities/Fido2/Fido2DomainUtils.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Bit.Core.Utilities.Fido2
|
||||
{
|
||||
public class Fido2DomainUtils
|
||||
{
|
||||
// TODO: This is a basic implementation of the domain validation logic, and is probably not correct.
|
||||
// It doesn't support IP-adresses, and it doesn't follow the algorithm in the spec:
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#is-a-registrable-domain-suffix-of-or-is-equal-to
|
||||
public static bool IsValidRpId(string rpId, string origin)
|
||||
{
|
||||
if (rpId == null || origin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: DomainName doesn't like it when we give it a URL with a protocol or port
|
||||
// So we remove the protocol and port here, while still supporting ipv6 shortform
|
||||
// https is enforced in the client, so we don't need to worry about that here
|
||||
var originWithoutProtocolOrPort = Regex.Replace(origin, @"(https?://)?([^:/]+)(:\d+)?(/.*)?", "$2$4");
|
||||
|
||||
if (rpId == originWithoutProtocolOrPort)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!DomainName.TryParse(rpId, out var parsedRpId) || !DomainName.TryParse(originWithoutProtocolOrPort, out var parsedOrgin))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return parsedOrgin.Tld == parsedRpId.Tld &&
|
||||
parsedOrgin.Domain == parsedRpId.Domain &&
|
||||
(parsedOrgin.SubDomain == parsedRpId.SubDomain || parsedOrgin.SubDomain.EndsWith(parsedRpId.SubDomain));
|
||||
}
|
||||
}
|
||||
}
|
40
test/Core.Test/Utilities/Fido2/Fido2DomainUtilsTests.cs
Normal file
40
test/Core.Test/Utilities/Fido2/Fido2DomainUtilsTests.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using Bit.Core.Utilities.Fido2;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Utilities.Fido2
|
||||
{
|
||||
public class Fido2DomainUtilsTests
|
||||
{
|
||||
[Theory]
|
||||
// From https://html.spec.whatwg.org/multipage/browsers.html#is-a-registrable-domain-suffix-of-or-is-equal-to
|
||||
// [InlineData("0.0.0.0", "0.0.0.0", true)] // IP-addresses not allowed by WebAuthn spec
|
||||
// [InlineData("0x10203", "0.1.2.3", true)]
|
||||
// [InlineData("[0::1]", "::1", true)]
|
||||
[InlineData("example.com", "example.com", true)]
|
||||
[InlineData("example.com", "example.com.", false)]
|
||||
[InlineData("example.com.", "example.com", false)]
|
||||
[InlineData("example.com", "www.example.com", true)]
|
||||
[InlineData("com", "example.com", false)]
|
||||
[InlineData("example", "example", true)]
|
||||
[InlineData("compute.amazonaws.com", "example.compute.amazonaws.com", false)]
|
||||
[InlineData("example.compute.amazonaws.com", "www.example.compute.amazonaws.com", false)]
|
||||
[InlineData("amazonaws.com", "www.example.compute.amazonaws.com", false)]
|
||||
[InlineData("amazonaws.com", "test.amazonaws.com", true)]
|
||||
// Custom tests
|
||||
[InlineData("sub.login.bitwarden.com", "https://login.bitwarden.com:1337", false)]
|
||||
[InlineData("passwordless.dev", "https://login.bitwarden.com:1337", false)]
|
||||
[InlineData("login.passwordless.dev", "https://login.bitwarden.com:1337", false)]
|
||||
[InlineData("bitwarden", "localhost", false)]
|
||||
[InlineData("bitwarden", "bitwarden", true)]
|
||||
[InlineData("127.0.0.1", "127.0.0.1", false)]
|
||||
[InlineData("localhost", "https://localhost:8080", true)]
|
||||
[InlineData("bitwarden.com", "https://bitwarden.com", true)]
|
||||
[InlineData("bitwarden.com", "https://login.bitwarden.com:1337", true)]
|
||||
[InlineData("login.bitwarden.com", "https://login.bitwarden.com:1337", true)]
|
||||
[InlineData("login.bitwarden.com", "https://sub.login.bitwarden.com:1337", true)]
|
||||
public void ValidateRpId(string rpId, string origin, bool isValid)
|
||||
{
|
||||
Assert.Equal(isValid, Fido2DomainUtils.IsValidRpId(rpId, origin));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user