From df7dc615532d3441f527374d18664c1a5a336de6 Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 21 Jan 2024 21:24:55 -0500 Subject: optional path enforcement and patch baseURL relative inclusion --- .../src/Essentials.Accounts.json | 5 +- .../src/SecurityProvider/AccountSecProvider.cs | 85 ++++++++++++---------- 2 files changed, 51 insertions(+), 39 deletions(-) (limited to 'plugins/VNLib.Plugins.Essentials.Accounts/src') diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/Essentials.Accounts.json b/plugins/VNLib.Plugins.Essentials.Accounts/src/Essentials.Accounts.json index 73529ee..8a345c5 100644 --- a/plugins/VNLib.Plugins.Essentials.Accounts/src/Essentials.Accounts.json +++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/Essentials.Accounts.json @@ -89,6 +89,9 @@ "pubkey_cookie_name": "client-id", "pubkey_signing_key_size": 32, - "strict_origin": false + "strict_origin": false, + "strict_path": false, + + //"allowed_origins": [ ] } } \ No newline at end of file diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs index 5847820..9f1d6ee 100644 --- a/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs +++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/SecurityProvider/AccountSecProvider.cs @@ -459,55 +459,58 @@ namespace VNLib.Plugins.Essentials.Accounts.SecurityProvider } } - //Check the subject (path) matches the request uri - if (data.RootElement.TryGetProperty("path", out JsonElement tokenPathEl) - && tokenPathEl.ValueKind == JsonValueKind.String) + if (_config.VerifyPath) { - - ReadOnlySpan unsafeUserPath = tokenPathEl.GetString(); - /* - * Query parameters are optional, so we need to check if the path contains a - * query, if so we can compare the entire path and query, otherwise we need to - * compare the path only - */ - if (unsafeUserPath.Contains("?", StringComparison.OrdinalIgnoreCase)) + //Check the subject (path) matches the request uri + if (data.RootElement.TryGetProperty("path", out JsonElement tokenPathEl) + && tokenPathEl.ValueKind == JsonValueKind.String) { - //Compare path and query when possible - string requestPath = entity.Server.RequestUri.PathAndQuery; - isValid &= unsafeUserPath.Equals(requestPath, StringComparison.OrdinalIgnoreCase); + ReadOnlySpan unsafeUserPath = tokenPathEl.GetString(); + /* + * Query parameters are optional, so we need to check if the path contains a + * query, if so we can compare the entire path and query, otherwise we need to + * compare the path only + */ + if (unsafeUserPath.Contains("?", StringComparison.OrdinalIgnoreCase)) + { + //Compare path and query when possible + string requestPath = entity.Server.RequestUri.PathAndQuery; + + isValid &= unsafeUserPath.Equals(requestPath, StringComparison.OrdinalIgnoreCase); - if (!isValid && _logger.IsEnabled(LogLevel.Debug)) + if (!isValid && _logger.IsEnabled(LogLevel.Debug)) + { + _logger.Debug("Client security OTP JWT path mismatch from {ip} : {current} != {token}", + entity.TrustedRemoteIp, + requestPath, + unsafeUserPath.ToString() + ); + } + } + else { - _logger.Debug("Client security OTP JWT path mismatch from {ip} : {current} != {token}", - entity.TrustedRemoteIp, - requestPath, - unsafeUserPath.ToString() - ); + //Use path only + string requestPath = entity.Server.RequestUri.LocalPath; + + //Compare path only + isValid &= unsafeUserPath.Equals(requestPath, StringComparison.OrdinalIgnoreCase); + + if (!isValid && _logger.IsEnabled(LogLevel.Debug)) + { + _logger.Debug("Client security OTP JWT path mismatch from {ip} : {current} != {token}", + entity.TrustedRemoteIp, + requestPath, + unsafeUserPath.ToString() + ); + } } } else { - //Use path only - string requestPath = entity.Server.RequestUri.LocalPath; - - //Compare path only - isValid &= unsafeUserPath.Equals(requestPath, StringComparison.OrdinalIgnoreCase); - - if (!isValid && _logger.IsEnabled(LogLevel.Debug)) - { - _logger.Debug("Client security OTP JWT path mismatch from {ip} : {current} != {token}", - entity.TrustedRemoteIp, - requestPath, - unsafeUserPath.ToString() - ); - } + isValid = false; } } - else - { - isValid = false; - } return isValid; } @@ -865,6 +868,12 @@ namespace VNLib.Plugins.Essentials.Accounts.SecurityProvider [JsonPropertyName("allowed_origins")] public string[]? AllowedOrigins { get; set; } + /// + /// Enforce strict path checking for the client's token + /// + [JsonPropertyName("strict_path")] + public bool VerifyPath { get; set; } = true; + void IOnConfigValidation.Validate() { //Validate the current instance -- cgit