Developer forum

Forum » Ecommerce - Standard features » Custom checkout handler return and receipt page

Custom checkout handler return and receipt page

Andrew Rushworth
Reply

Hi,

Hoping you can offer advice.
Dynamicweb 9.17 using rapido.

The checkout handlers we have redirect to the payment gateway and contain a success and failure url: 
These urls are in the following format: /Default.aspx?ID={pagid}&CheckoutHandlerOrderID={OrderID}&redirect=false
The payment provider then posts results to url which invokes the checkout handler to process the Redirect().

I have 2 main questions:
1)  CheckoutHandlerOrderID: Is this the only identifier the checkout hander can use to identify the order? The reason i ask is that the order numbers are sequential, so could easily be manipulated. It would be better if a GUID was used to identify the order.

2)Receipt Page: This is also an issue when  it comes to showing the receipt page after success, as the receipt page does not authenticate the user and thus customers can manipulate the order number to see receipts and data of other customers.


 


Replies

 
Andrew Rushworth
Reply

Sorry one more issue is that when the checkouthandler is invoked when the payment gateway returns to the site using the url,

The checkout handler processes the order and then redirects to
CompletedOrderId={OrderID}&CompletedOrderSecret={order secret}

Ideally we dont' want to expose the order information in the url redirects - i would prefer that is uses an obsure order references or encrypted string in the urls.

Has anyone implemented a way to secure the url parameters representing and the receipt page?

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

1) Is CheckoutHandlerOrderID the only identifier?

Yes — CheckoutHandler.RedirectToCheckoutHandler() resolves the order purely from CheckoutHandlerOrderID/s_CheckoutHandlerOrderID, with no secondary secret check on the way in. But this only matters for confidentiality, not integrity: an attacker can cause Redirect() to be invoked for someone else's order, but each checkout handler's Redirect() implementation independently validates the payment with the gateway (transaction ID, signature/hash from the gateway, gateway's own reference for that order) before calling SetOrderComplete. So guessing/incrementing CheckoutHandlerOrderID alone can't complete or tamper with another customer's order — the gateway-side validation is the actual security boundary, not the order id.  

But you're right that it's guessable/enumerable, so it shouldn't be trusted as an authorization token — and it isn't used as one for the completion step. It's only used as a lookup key, which is fine.

2) Receipt page manipulation

The receipt page is not actually unauthenticated by order id alone:

  • The receipt/completed-order flow requires both CompletedOrderId and CompletedOrderSecret in the query string.
  • CompletedOrderSecret is checked against order.Secret which is a Guid.NewGuid().ToString("N") generated server-side - a 128-bit random value, not derived from the order id and not guessable/enumerable.
  • If the secret doesn't match, GetOrder() returns null and the receipt isn't shown.

So Order.Id alone can't be used to view someone else's receipt — you'd also need their Secret GUID, which isn't derivable from the order id/number. This already is effectively "an obscure/encrypted-strength reference," just implemented as a random GUID token appended alongside the id rather than as a single opaque token.

On your follow-up (exposing CompletedOrderId/CompletedOrderSecret in the URL):

This is a legitimate, narrower concern than "no auth at all" — it's about the secret being bearer-token-like and living in the URL. The token is not time limited as the receipt page should be accessible for some time. A leak or a guess is first of all not a security issue per se, and if you want you can move the receipt on another page carrying the checkout app and behind a permission check. Maybe combined with simple template logic that will time limit how long a receipt can be seen when anonymous.

BR Nicolai  

 
Andrew Rushworth
Reply

HI Nicolai,

Thanks for the detailed response. 
We do validate the payment so that is secure.

The issue is that if i call a checkout handler url:
https://mysite.com/checkout?CheckoutHandlerOrderID=ORD94644&redirect=true
OR
https://mysite.com/checkout?CheckoutHandlerOrderID=ORD94640&redirect=true

And these two orders are complete, it then redirects you to the receipt page with the secret for the order:
CompletedOrderId=ORD94640&CompletedOrderSecret=94ca3823b2bb450eaceb2568b34b1521
CompletedOrderId=ORD94644&CompletedOrderSecret=fce7c7a4361f408da7e22562a7413526

So you dont' have to guess the OrderSecret, the checkouthandler will pick it up on the redirect.

Not sure if this makes sense.
 

 

You must be logged in to post in the forum