====== HMAC Product Verification: Locking Down your Add-To-Cart Links and Forms ======
===== The What & Why =====
==== What Is FoxyCart's HMAC Product Verification? ====
FoxyCart's HMAC Product Verification is a cryptographic method to prevent tampering with your product links and forms, available as of [[:v:0.7.0/|FoxyCart v0.7.0]], based on [[wp>HMAC|HMAC]] [[wp>SHA_hash_functions|SHA-256]]. We know that sounds terrifying, but please read on and it will make more sense. (And //great news!// You can likely implement this without actually having to know anything about the details.)
We recommend taking a moment to familiarize yourself with [[wp>Cryptographic_hash_function|cryptographic hash functions]], as they're quite interesting, but the short version is this: Using a hash (specifically with HMAC) provides a very secure way to ensure data isn't modified. So your add-to-cart links and forms can be locked down, preventing a nefarious user from modifying your products.
==== The Potential Risks & Solutions ====
If you do not implement FoxyCart's HMAC cart verification functionality then your products are relatively easily modifiable by web-savvy users. This means that your Product A sold at $20 could be added to the cart at $10 or $1, or added to the cart with the wrong category (possibly affecting taxes or shipping) or etc.
While this certainly can be a major problem, there are multiple ways to minimize the risk. The most common approach taken by stores with smaller order volume is "eyeballing" orders and doing sanity checks prior to delivery. If only one or two people handle the fulfillment and are familiar with the products and pricing, that is often enough to prevent fulfillment of a spoofed order.
Another option is to verify orders automatically using the [[transaction_xml_datafeed|XML datafeed]], comparing the transactions and products against the prices stored in your site's database and alerting on error. Many higher-volume stores take this approach, and it is built into some of the FoxyCart integrations supplied by 3rd parties.
While both of those options can work well depending on your needs, the most robust method of product validation is to use FoxyCart's HMAC Verification. This method prevents spoofing attempts by requiring all links and form values to be "signed" using your "secret" (which in this case is your API key). Only values signed with your secret key will be accepted by FoxyCart, allowing you to prevent product spoofing before orders are placed.
==== Do You Need FoxyCart's HMAC Product Verification? =====
It really depends on a few things, including your order volume, your order processing flow, the nature of your products, and your cost to implement versus the potential payoff. That said, if you're worried about price spoofing we strongly recommend implementing it. If you only have a few products then it's only a little extra work up front. If you have many products then it can be added to your CMS and handled automatically by your site, in the background.
===== Language Specific Examples & Helper Files =====
While you certainly can build your validation functionality from scratch, it may be a boon to use an existing library. Currently we only have official code for PHP but if you're interested in porting the PHP version to another language please [[http://forum.foxycart.com/|let us know]] and we'd be happy to provide assistance.
==== PHP: Automatic Validation with Minimal Effort ====
[[http://github.com/FoxyCart/FoxyCart-Cart-Validation--PHP|FoxyCart Cart Validation, PHP]] (on GitHub) to **automatically sign an entire HTML page** (recommended) or to sign individual links, inputs. This code is capable of automatically signing //all links and forms// on an entire HTML page, which makes it trivially easy to add to an existing site or CMS.
===== The How: Implementation Details =====
==== A Basic Overview ====
The basic idea is to sign each and every product option, excluding things that aren't actually "product options" like ''cart=checkout'' or ''output=json'' and such. We do this by first concatenating the following values:
* the product code,
* the form element's ''name'',
* and the form element's ''value'' (if it's a pre-set value) or the string ''--OPEN--'' (if it's an open-input field, like ''quantity'').
We then HMAC SHA-256 that string, and append it to the ''name'' attribute of the input with double pipes (''||'') in between. For example, if we had a product with a code of ''ABC123'' and an input with ''name="name" value="My Example Product"'', we'd hash the string ''ABC123nameMy Example Product''. We'd then append the hash to the ''name'' attribute like this:
Add To Cart
(We're going to be using a form as an example, but all of it holds true for links as well.)
You might realize, however, that this approach wouldn't work for ''