Fix: Archived invoices shouldn't be browsable by non authenticated users (#6588)

* fix: return 403 when unauthenticated user accesses an archived invoice receipt

* refactor: simplify archived invoice access check with pattern matching

* Return 404 for unauthorized users accessing archived invoice

Co-authored-by: d11n <mail@dennisreimann.de>

* feat: add archived invoice validation for unauthenticated access in Checkout and GetStatus

* test: add test case for unauthorized access to archived invoice returning not found

* test: add unauthorized checkout test for archived invoice

* Commenting code and adding test case for GetStatus

---------

Co-authored-by: d11n <mail@dennisreimann.de>
Co-authored-by: rockstardev <5191402+rockstardev@users.noreply.github.com>
This commit is contained in:
ThiagoOyo
2025-03-06 05:45:53 -03:00
committed by GitHub
parent 7b4fd0e40c
commit 9bff84f90f
2 changed files with 39 additions and 0 deletions

View File

@@ -198,6 +198,9 @@ namespace BTCPayServer.Controllers
var store = await _StoreRepository.GetStoreByInvoiceId(i.Id);
if (store is null)
return NotFound();
if (!await ValidateAccessForArchivedInvoice(i))
return NotFound();
var receipt = InvoiceDataBase.ReceiptOptions.Merge(store.GetStoreBlob().ReceiptOptions, i.ReceiptOptions);
if (receipt.Enabled is not true)
@@ -727,6 +730,9 @@ namespace BTCPayServer.Controllers
if (invoice == null)
return null;
if (!await ValidateAccessForArchivedInvoice(invoice))
return null;
var store = await _StoreRepository.FindStore(invoice.StoreId);
if (store == null)
return null;
@@ -1000,6 +1006,10 @@ namespace BTCPayServer.Controllers
var invoice = await _InvoiceRepository.GetInvoice(invoiceId);
if (invoice == null || invoice.Status == InvoiceStatus.Settled || invoice.Status == InvoiceStatus.Invalid || invoice.Status == InvoiceStatus.Expired)
return NotFound();
if (!await ValidateAccessForArchivedInvoice(invoice))
return NotFound();
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
CompositeDisposable leases = new CompositeDisposable();
try
@@ -1314,5 +1324,12 @@ namespace BTCPayServer.Controllers
});
return RedirectToAction(nameof(ListInvoices), new { storeId });
}
private async Task<bool> ValidateAccessForArchivedInvoice(InvoiceEntity invoice)
{
if (!invoice.Archived) return true;
var authorizationResult = await _authorizationService.AuthorizeAsync(User, invoice.StoreId, Policies.CanViewInvoices);
return authorizationResult.Succeeded;
}
}
}