Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is a neat idea, but there is at least one subtlety: you need to make sure that it is not possible to cut-and-paste HMAC'd prices from one web page into another. Otherwise the user could ask for a page for an item with a price of $1, receive an HMAC on "$1", and paste that into a page for a different item.

Two possible ways to do this:

1) Use a different HMAC key for each page you generate. 2) HMAC the pair (price,nonce) where nonce never repeats from one page to another. The server has to keep the nonce, as well, i.e. is not obtained from the web page.



A simple one-way hash will provide sufficient security for most cases. Assuming you're representing items for sale in a Javascript array, you might send data like this to the browser:

  var forSale = {
    "book": {"price": 19.95, "description": "a book", "checksum": "c6da835c1fd2ee98d68eee3912dd199e41c82a32"}
  }
The value for 'checksum' is just a SHA1 hex digest of the ('book', '19.95', 'secret'), joined by tab characters. It can be included as a hidden form field or invisible element within your page; it doesn't matter so long as you can capture it and POST is along with the item + price.

In your order-processing logic, just check that the hash verifies with your secret key ('secret' in the above), and you know with a reasonable degree of certainty that the original page was one generated by your server.


That would work, but I don't do order fulfillment. e-junkie does. They get to keep the IPN and Google payment notification interfaces, an email server to send out registration keys, bunches o' reporting code, and integration to the company that stamps CDs for me.

The cart posts directly to them, so hypothetically assuming I generated a secret and passed it over, they'd process the order anyhow and then tell me "By the way, your website passed this secret with the order -- do whatever with it", after which point a) the customer would have a registration key and b) if they ordered a CD, it would be scheduled to ship already.

Which is a long way of saying "There are ways to make this setup more secure but they'd involve me having to rewrite large portions of my business processes." Like I mentioned: it would cost me a lot of time at a very minor increase in security.

Probably illusory, actually. No amount of securing my cart will protect me from this attack: buy the software, write me an email saying "You offer an unconditional guarantee. I'd like a refund." And there is absolutely nothing that anyone could say or do which would make me stop offering that unconditional guarantee, because it is practically a license to print money. (To anyone who produces a low-marginal-cost product or service: if you do not have a guarantee, start A/B testing one. Its the closest thing in life to free money.)


I remember reading one of the "hacking exposed" books (the exact one I can't remember now), where there was an incident where an online store used values in the webpage itself to handle the prices of goods. In the example in the book, the hackers had replaced $45 list price with $1 giving huge discounts to the purchasers. And to make things even worse, some of the hackers would order dozens of shirts (at $1 each) and then return them for full price.

It might have been an earlier edition of this one, but I do remember the bright red cover: http://www.amazon.com/Hacking-Exposed-Web-Applications-2nd/d...


Do you use the same secret for each page generated? If so, checking that the hash verifies with your secret key alone does not prevent a cut and paste attack where an adversary asks for a web page with the SHA1 digest of an item worth '1.00' and then pastes that item into the web page for an item worth '19.95'. You need some additional checking that the "forSale" supplied not only was created by you, but was created by you for use in this particular page and context.

A separate issue is that using this hash(message, secret) construction has problems if the underlying hash function has chosen-prefix collisions. MD5 has this problem already. While no one knows how to generate such collisions for SHA1, the fact that its design is close to MD5 is cause for concern. In contrast, if you use HMAC, you have confidence that the data was generated by you with much weaker assumptions on the hash function. The wikipedia page for HMAC has some useful discussion here and pseudocode: http://en.wikipedia.org/wiki/HMAC




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: