NFC-99 Web eID for mobile support#64
NFC-99 Web eID for mobile support#64SanderKondratjevNortal wants to merge 5 commits intoweb-eid-mobilefrom
Conversation
0315bc1 to
076734c
Compare
46c9709 to
025a58c
Compare
example/src/WebEid.AspNetCore.Example/Controllers/Api/AuthController.cs
Outdated
Show resolved
Hide resolved
|
|
||
| const path = window.location.pathname; | ||
| let endpoint; | ||
| if (path === "/sign/mobile/certificate") { |
There was a problem hiding this comment.
As discussed during Java code review, you can just validate the path and then reuse it directly:
const path = window.location.pathname;
const allowedEndpoints = ["/sign/mobile/certificate", "/sign/mobile/signature"];
if (!allowedEndpoints.includes(path)) {
const error = new Error("Unexpected callback path: " + path);
error.code = "INVALID_CALLBACK_PATH";
throw error;
}
example/src/WebEid.AspNetCore.Example/Signing/MobileSigningService.cs
Outdated
Show resolved
Hide resolved
example/src/WebEid.AspNetCore.Example/Signing/MobileSigningService.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/CertValidators/ISubjectCertificateValidator.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/CertValidators/SubjectCertificateNotRevokedValidator.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/CertValidators/SubjectCertificatePolicyValidator.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/CertValidators/SubjectCertificateTrustedValidator.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/CertValidators/SubjectCertificateValidatorBatch.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/VersionValidators/AuthTokenVersion1Validator.cs
Show resolved
Hide resolved
src/WebEid.Security/Validator/VersionValidators/AuthTokenVersion11Validator.cs
Outdated
Show resolved
Hide resolved
src/WebEid.Security/Validator/VersionValidators/AuthTokenVersion11Validator.cs
Show resolved
Hide resolved
8561d8d to
dba0714
Compare
| AddNewClaimIfCertificateHasData(claims, ClaimTypes.Name, certificate.GetSubjectCn); | ||
|
|
||
| var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); | ||
| if (!string.IsNullOrEmpty(authToken.UnverifiedSigningCertificate)) |
There was a problem hiding this comment.
You need a v1.1 format check here to avoid the following attack (also in Java):
- Attacker gets a valid web-eid:1 auth token from client-side flow to log in normally
- Before posting to /auth/login, attacker edits JSON and adds:
- unverifiedSigningCertificate: any base64 cert they want
- supportedSignatureAlgorithms: any list
- Server validates token as v1, v1 validator ignores these two fields and authentication succeeds
- AuthController stores those untrusted values into auth cookie claims (signingCertificate, supportedSignatureAlgorithms)
- Later attacker calls /sign/mobile/init; MobileSigningService sees those claims, skips certificate initialization and builds mobile sign request directly from injected claim values
- Signing flow now runs with attacker-chosen signing certificate metadata, not server-validated metadata
This is not immediately dangerous, but it bypasses v1.1 safety checks and may introduce some subtle attacks against real systems that we cannot even foresee at the moment.
A simple
var isV11 = authToken.Format?.StartsWith("web-eid:1.1", StringComparison.OrdinalIgnoreCase) == true;
check and using isV11 in the if block would guard against this.
|
|
||
| bool hasInvalid = | ||
| algorithms.Any(a => | ||
| !SupportedSigningCryptoAlgorithms.Contains(a.CryptoAlgorithm) || |
There was a problem hiding this comment.
a can be null here, then a.CryptoAlgorithm will fail with NullReferenceException.
src/WebEid.Security.Tests/Validator/VersionValidators/AuthTokenV11CertificateTest.cs
Show resolved
Hide resolved
…eid example Signed-off-by: Sander Kondratjev <sander.kondratjev@nortal.com>
…bile auth error layout
Signed-off-by: Sander Kondratjev <sander.kondratjev@nortal.com>
d50a7c8 to
15e35e1
Compare
bd1edc8 to
265952a
Compare
| /// Validates the purpose of the user certificate from the authentication token. | ||
| /// </summary> | ||
| public class SubjectCertificatePurposeValidator : ISubjectCertificateValidator | ||
| internal class SubjectCertificatePurposeValidator : ISubjectCertificateValidator |
There was a problem hiding this comment.
Can this be sealed as others?
| internal class SubjectCertificatePurposeValidator : ISubjectCertificateValidator | |
| internal sealed class SubjectCertificatePurposeValidator : ISubjectCertificateValidator |
|
|
||
| const path = window.location.pathname; | ||
| let endpoint; | ||
| if (path === "/sign/mobile/certificate") { |
| } | ||
| }); | ||
|
|
||
| function isMobileDevice() { |
There was a problem hiding this comment.
We should extract this function to a separate module and reuse it to make code more DRY.
| AddNewClaimIfCertificateHasData(claims, ClaimTypes.Name, certificate.GetSubjectCn); | ||
|
|
||
| var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); | ||
| if (!string.IsNullOrEmpty(authToken.UnverifiedSigningCertificate)) |
| var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); | ||
| var signingCertificate = authToken.UnverifiedSigningCertificates != null && | ||
| authToken.UnverifiedSigningCertificates.Count > 0 | ||
| ? authToken.UnverifiedSigningCertificates[0] |
There was a problem hiding this comment.
Noting that currently a user authenticating with multiple signing certificates cannot choose a non-first certificate during signing, but I guess this is intended.
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.3" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.3" /> | ||
| <PackageReference Include="Microsoft.Identity.Web" Version="3.8.4" /> |
There was a problem hiding this comment.
Should we update other packages as well?
| using Exceptions; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.IdentityModel.Tokens; | ||
| using Newtonsoft.Json; |
There was a problem hiding this comment.
Let's use System.Text.Json instead of Newtonsoft.Json and remove Newtonsoft.Json from project. Also update project dependencies and .NET version to 10 like with example.
Signed-off-by: Sander Kondratjev sander.kondratjev@nortal.com