payments #53

Merged
khwezi merged 6 commits from payments into master 2026-06-01 09:21:01 +02:00
Showing only changes of commit c4f73fd999 - Show all commits
@@ -35,7 +35,6 @@ public sealed partial class HashService(IHashids hasher, IOptions<HasherSettings
if (string.IsNullOrWhiteSpace(incomingSignature)) if (string.IsNullOrWhiteSpace(incomingSignature))
return Result.Fail<bool>("Validation failed: Missing signature string parameter."); return Result.Fail<bool>("Validation failed: Missing signature string parameter.");
// 1. Sort the parameters alphabetically and exclude the signature parameter to prevent recursive checking
var sortedFields = incomingFormData var sortedFields = incomingFormData
.Where(field => field.Key != "signature") .Where(field => field.Key != "signature")
.OrderBy(field => field.Key) .OrderBy(field => field.Key)
@@ -43,19 +42,14 @@ public sealed partial class HashService(IHashids hasher, IOptions<HasherSettings
string payload = string.Join("&", sortedFields); string payload = string.Join("&", sortedFields);
// 2. Append the secure, passphrase injected into the container pod from your environment variables
if (!string.IsNullOrWhiteSpace(settings.PayfastPassphrase)) if (!string.IsNullOrWhiteSpace(settings.PayfastPassphrase))
{
payload += $"&passphrase={Uri.EscapeDataString(settings.PayfastPassphrase).Replace("%20", "+")}"; payload += $"&passphrase={Uri.EscapeDataString(settings.PayfastPassphrase).Replace("%20", "+")}";
}
// 3. Compute localized hex token
var localHashResult = ComputeMd5Hash(payload); var localHashResult = ComputeMd5Hash(payload);
if (!localHashResult.IsSuccess) if (!localHashResult.IsSuccess)
return Result.Fail<bool>(localHashResult.Errors); return Result.Fail<bool>(localHashResult.Errors);
// 4. Constant-time secure text comparison to fully block timing analysis attacks
bool isValid = string.Equals(localHashResult.Value, incomingSignature, StringComparison.OrdinalIgnoreCase); bool isValid = string.Equals(localHashResult.Value, incomingSignature, StringComparison.OrdinalIgnoreCase);
return Result.Ok(isValid); return Result.Ok(isValid);