tags:

views:

115

answers:

4

Hi guys,

We're deving a website that's designed to handle online payments. We were wondering, is it OK to pass an Order / Transaction Id through the querystring whilst in the process of making a payment? We'd rather not store this Id in a session variable because of server overhead, so we were thinking storing it in the querystring would be suitable.

Any thoughts on this? Particularly from a security point of view.

Many thanks.

A: 

you should be capturing the order in your db. It is not advisable to pass it in a query string.

Rick J
+1  A: 

Passing sensitive infomation (e.g. order numbers) in a query string is generally a bad idea for a number of reasons:

1) The GET url is passed as plaintext, which means anything between the client and the server can read and capture the order number from the request. If your server relies on the order number to do anything important, then it's a wide open invitation for abuse.

2) Most proxies and access logs will log web addresses including the GET query, meaning that the customer's order number will be stored in access logs on any number of machines (including your server). You are most likely unable to control this behavior, which is VERY BAD(TM).

To make your app secure, you should store the actual order number in a session on the server, and pass it to the user in a cookie (preferably encrypted). Passing anything important in plaintext is prone to abuse and should not be attempted for anything important.

futureelite7
+2  A: 

Trying to make your service stateless is a worthy goal. Whether having order IDs in query strings is "safe" depends on a lot of things, though. The main things you may need to worry about are:

  • users altering their order ID
  • order IDs "leaking" to third-parties
  • order IDs being predicted by third-parties

I say "may" because which things you actually need to worry about depend on details of your system. What are the consequences of these things happening? Depending on the details of your system these may be harmless or they may be very serious.

The easiest problem to solve is the "leaking" issue. Use HTTPS. This not only prevents "eavesdroppers", but also prevents leaks due to proxy logs and Referer headers.

The prediction issue can be solved by encrypting (yes, in addition to HTTPS -- we don't want the end-user decrypting this either) the order ID that appears in the query string. That way someone can't just inc/decrement the query string to find another order ID. (This also prevents users from easily figuring out the total number of orders in your system, which may be desirable.)

You can solve the issue of the user altering their order ID by either recording who an order ID belongs to when it is first allocated, or by including a secure signature of the (user, orderid) pair as a query parameter. Then a user can only change their order ID to one they already own, which at least prevents them from screwing around with someone else's orders. If you do this, you probably don't need to do the encryption of order IDs, unless you want to prevent users from knowing how many orders exist.

These are just some ideas. Which of these apply to your system depend on the factors I mentioned earlier.

Laurence Gonsalves
A: 

Encrypting the Order ID would be fine - you might also consider hashing the original Order ID, and passing it and the hashed token in the querystring. I don't see this as a security risk as I wouldn't consider the Order ID as sensitive data. All you need to do is ensure that the user hasn't manipulated it in any way.

http://www.duncangunn.me.uk/dasblog/2009/08/01/VerifyingTheIntegrityOfQueryStringParameters.aspx

Duncan