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.
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.)
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...
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
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.