From 18bdb82fbe144b9acfe3878ed4a688f8d229e035 Mon Sep 17 00:00:00 2001 From: rockstardev <5191402+rockstardev@users.noreply.github.com> Date: Tue, 3 Jun 2025 22:35:44 -0500 Subject: [PATCH] Sanitizing jsonPath before calling SelectToken (#6767) --- .../HostedServices/Webhooks/WebhookSender.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs b/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs index 41c435339..36d8de862 100644 --- a/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs +++ b/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs @@ -288,28 +288,41 @@ public class WebhookSender( protected static string InterpolateJsonField(string str, string fieldName, JObject obj) { fieldName += "."; - //find all instance of {fieldName*} instead str, then run obj.SelectToken(*) on it + // Regex pattern to validate JSONPath: alphanumeric, underscore, dot, hyphen, square brackets, asterisk, single/double quotes + const string jsonPathPattern = @"^[a-zA-Z0-9_\.\-\[\]\*'""]*$"; + + //find all instance of {fieldName*} in str, then run obj.SelectToken(*) on it while (true) { var start = str.IndexOf($"{{{fieldName}", StringComparison.InvariantCultureIgnoreCase); if (start == -1) break; - start += fieldName.Length + 1; + + start += fieldName.Length + 1; // Move past the { var end = str.IndexOf("}", start, StringComparison.InvariantCultureIgnoreCase); if (end == -1) break; + var jsonpath = str.Substring(start, end - start); var result = string.Empty; + try { if (string.IsNullOrEmpty(jsonpath)) + { result = obj.ToString(); - else - result = obj.SelectToken(jsonpath)?.ToString(); + } + else if (System.Text.RegularExpressions.Regex.IsMatch(jsonpath, jsonPathPattern)) + { + // Only process if JSONPath is valid + result = obj.SelectToken(jsonpath)?.ToString() ?? string.Empty; + } + // If jsonpath doesn't match the pattern, result remains empty string } - catch (Exception) + catch (Newtonsoft.Json.JsonException) { - // ignored + // Handle JSON parsing errors (e.g., invalid JSONPath syntax) + result = string.Empty; } str = str.Replace($"{{{fieldName}{jsonpath}}}", result);