security: remove callback URL from user input — read from FrontOfficeBaseUrl config
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 9m28s

- PackageService: build callback URL from FrontOfficeBaseUrl config instead of request.CallbackUrl
- TransactionsService: same fix — callback URL from config
- Prevents potential open redirect vulnerability (user could send arbitrary URL)

All callback URLs now come from appsettings FrontOfficeBaseUrl or CmsBaseUrl.
This commit is contained in:
masoodafar-web
2026-02-27 22:20:04 +03:30
parent ed2b20a98e
commit 01073084ab
2 changed files with 11 additions and 7 deletions
@@ -182,9 +182,9 @@ public class PackageService : PackageContract.PackageContractBase
.Select(u => new { u.Mobile })
.FirstOrDefaultAsync(context.CancellationToken);
// Embed orderId in callback URL so FrontOffice can pass it back for verification
var separator = request.CallbackUrl.Contains('?') ? "&" : "?";
var callbackWithOrder = $"{request.CallbackUrl}{separator}orderId={purchase.Id}";
// Callback URL از config — نه از ورودی کاربر (امنیت)
var frontOfficeBaseUrl = _configuration["FrontOfficeBaseUrl"] ?? "https://localhost:5268";
var callbackUrl = $"{frontOfficeBaseUrl}/profile/payment-callback?orderId={purchase.Id}";
var paymentResult = await _paymentGateway.InitiatePaymentAsync(new PaymentRequest
{
@@ -192,7 +192,7 @@ public class PackageService : PackageContract.PackageContractBase
UserId = userId,
Mobile = user?.Mobile ?? string.Empty,
Description = $"خرید پکیج {package.Title}",
CallbackUrl = callbackWithOrder
CallbackUrl = callbackUrl
}, context.CancellationToken);
if (!paymentResult.IsSuccess)
@@ -216,7 +216,7 @@ public class PackageService : PackageContract.PackageContractBase
GatewayProvider = _configuration["PaymentProvider"] ?? "zarinpal",
MerchantId = _configuration["ZarinPal:MerchantId"] ?? "",
Amount = package.Price,
CallbackUrl = request.CallbackUrl,
CallbackUrl = callbackUrl,
Description = $"خرید پکیج {package.Title}",
Mobile = user?.Mobile,
UserId = userId,