I'm just getting started integrating the SIM API. I was reading through the SIM guide (the January 2016 version), and I noticed that the x_fp_hash value only covers the login ID, sequence number, timestamp, amount, and optionally currency code. It doesn't cover any other fields, and I don't see any validated fingerprint field that does.
My concern is that this means authorize.net isn't guaranteed to get the same form data that my server has prepared, even with consistent use of HTTPS. The values not covered by the fingerprint may be altered by the client, and authorize.net won't notice a problem.
For example, let's say my server prepares a POST form for the user, containing the standard API fields and a number of optional fields, and it sends it to the user via HTTPS. At this point, there's nothing stopping the user from using common browser tools to change the values of any of the fields that aren't covered by the fingerprint, and then submitting them to authorize.net (again, even though HTTPS is used). Since those altered fields aren't covered by the fingerprint, authorize.net can't tell that they were altered.
I think there is a reasonable expectation that the fields sent by my server should either be received by authorize.net intact, or else the user should not be able to proceed with the payment.
One possible solution is to support a new field that may be used instead of x_fp_hash (for security reasons, they must not be combined in the same request), which serves a similar purpose, but would also cover all submitted fields. I would suggest doing something similar to what OAuth does for signatures, which is roughly this:
This gives us something like:
This string would then be the input for the HMAC. Since this is 2016, I would suggest HMAC-SHA512, which gives effectively 128 bits of security in the post-quantum era.
It sounds like a more complex solution than the current fingerprint scheme, but it actually takes less code to implement in some languages. For example, in PHP, this is just:
ksort($fields); $serialized = http_build_query($fields, '', '&', \PHP_QUERY_RFC3986); $fields['x_fp_fullhash'] = hash_hmac('sha512', $serialized, $transaction_key);
I'm confused. By the way you're interpreting that page, the Payment Transactions API is also no longer actively maintained or enchanced, since the page lists AIM and says it's renamed to Payment Transactions. If the Payment Transactions API is also no longer maintained, that doesn't leave much.
http://developer.authorize.net/api/ still lists Payment Form (SIM). I don't see anything in the site saying that the Payment Form is no longer actively maintained or to not to use it in new projects.