I believe it will be difficult to source a definitive answer to this question of why a CSRF token is "needed" in Magento's add to cart GET action. I'll make an attempt to interpret its purpose. I'm by no means a security expert and this is my interpretation of CSRF in this particular context.
Context
From owasp.org
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request.
One example of this attack is embedding a hidden image in an email or an alternate webpage:
<img src="http://shop.com/cart/add?sku=sprocket&qty=5" width="0" height="0" border="0">
The web server would not differentiate where the request came from and would faithfully add the item to that user's cart.
The goal of preventing CSRF attacks is to prevent state-changing requests. Adding an item to a cart would be considered as change in state. In general, I would consider this is a harmless state change compared to submitting an order, transferring funds or updating an email address.
Regarding state changes and HTTP methods, RFC 2616 says the following:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe".
Magento and CSRF
Magento does implement CSRF prevention mechanism for both admin and frontend areas by using a token (form key). I would assume that Magento's goal, as a platform meant to be built upon by other developers, is to secure all state changing requests. The reason being that they have no idea what the implementing developers or 3rd party extensions may inadvertently expose. It's safer to secure all state changing requests than to have something exposed by a 3rd party module and be bad PR for the platform. I don't actually know if all state changing requests are secured from CSRF attacks.
One thing to note is that Magento does not always use a form key to protect state changing requests. For instance, the Delete From Cart (/checkout/cart/delete/id/{ID}
) and Delete Customer Address (/customer/address/delete/id/{ID}
) requests are both GET requests that pass in an Entity ID. The controller (or models) then handle ensuring that the user is authorized to remove those entity records (modify state). These are two instances where Magento doesn't follow RFC 2616. To be fair, for some use cases it might not be practical or necessary to do so.
It appears that the form key check in the Mage_Checkout_CartController::addAction
method was added in version 1.8. From the release notes we have the following to go off of:
Resolved issues that could have resulted in Cross-Site Request Forgery (CSRF) in the web store.
Unfortunately the language is vague and the "could have" leads me to believe it was due to the assumption I stated earlier: secure state changing requests. There might be a possibility of sending additional parameters which cause some sort of unintended behavior: /checkout/cart/add/product/337/email/new@address.com/password/l33tp4ssw0rd
The idea being that by adding something to the cart there's some bit of code (core or 3rd party) which happens to be triggered during add to cart, e.g. via some event dispatched.
It seems unlikely that such a vulnerability exists out of the box and if it does one would hope Magento would do a better job of disclosing the details/risks. One risk I could see is that Magento blindly stores the request parameters during the add to cart in the product_options
column of the sales order items table (see: info_buyRequest
). In theory someone could trick a group of users into adding items to their cart with weird query parameters and that would get stored into sales_flat_quote_item_option
table and eventually the sales_flat_order_item
table if they're also able to get those users to convert. This seems very unlikely to me in most cases.
Add to Cart Form Key Issues
One of the big issues people run into with a FPC implementation and CSRF tokens is they end up getting cached. The first client that warms the cache generates the token, when the second client gets a cache HIT they now have been given a page with the first users token. When submitting the form the tokens wont match.
Magento Enterprise uses placeholders to find/replace the form keys in cached pages. Varnish implementations will likley use an ESI to wherever a form key is used.
I would be curious to know whether some the more popular "ajax cart" extensions end up checking the CSRF token during their add to cart requests.
The one feature request where I end up foregoing the CSRF token for the add to cart action is allowing the ability to create add to cart links for use in emails or other web sites (social media). Sometimes marketing wants to have users directly add an item to the cart and redirect to the cart or checkout immediately. This can't easily be done if a CSRF token is required. I'd only recommend this if you're comfortable with the level of risk and trust your own and any 3rd party code.
Best Answer
In short, yes. CE 1.7 is still vulnerable to those specific attacks because no security release has been issued which contains a patch.
In the case of the latter one, a session fixation attack, the change is an upgrade in the security practices which Magento already used to stay in line with current security best-practices. Not something likely to be issued to CE 1.7 if they do issue a patch with the CSRF fixes.
The real question is what exactly were these CSRF vulnerabilities which were fixed? Doubtless a good thing that they did not include specifics in the release notes, thus further jeopardizing all prior releases, but it would be nice to know for the sake of patching old implementations.
UPDATE #1: Upon reaching out to Magento to find out when they will be issuing patches for the above vulnerabilities, I received the following reply:
I'll post back further details here as I get them, and will be doing my best to get patches issued since it seems that there are not currently any patches in existence.
UPDATE #2: After back and forth with the support team, I was able to obtain a proper patch for Magento EE 1.12.0.2. No patch was issued for Magento CE 1.7.0.2, and as far as the technician who looked into it internally for me knows, there are no plans to release an official patch for CE 1.7.x instead resolving the issues only in the upcoming CE 1.8 stable release.
As for the EE specific patch file, I cannot post it (or the patch application tool) here directly since it would most undoubtedly be in violation of NDA between Magento and myself personally and the company for which I work. The name of the relevant patch is: "PATCH_SUPEE-1513_EE_1.12.0.2_v1.sh" — If you have the Enterprise Edition or a client using it, you should be able to request this patch from the Magento support team along with a note about the CSRF vulnerabilities which it is supposed to fix.
For CE 1.7.0.2 users, I've taken the freedom to generate a patch file (based on the patch provided by Magento) which includes only the hunks of code which alter Magento CE 1.7.0.2 core code files. In normal fashion, it includes irrelevant bits of added comments and adjusted formatting along with the relevant code changes. Creating this required manually altering the original patch to apply it using the provided patch applying tool, then using git to generate a patch based on the applied changes.
The patch file which I've created can be downloaded from this gist: https://gist.github.com/davidalger/5938568
To apply the patch, first cd into the root of your Magento installation and run the following command:
patch -p1 -i ./Magento_CE_1.7.0.2_v1-CSRF_Patch.diff
The EE specific patch included form key validation checks to Enterprise specific controllers, alterations to enterprise/default and enterprise/iphone template files to include form keys in the forms being used for the patched controller actions, and additional Full Page Cache funtionality to properly account for passing form keys back and forth on cached pages.
DISCLAIMER: I have NOT TESTED either the EE patch provided by Magento nor the patch I've uploaded to the linked gist. The patch provided in the referenced gist is provided with NO WARRANTY and may or may not fully resolve the vulnerabilities referenced in the CE 1.8 release notes. As an untested patch, there is also no guarantee that it functions in whole or part. I.e. use at your own risk, and take due diligence to test before deploying to a production environment. If you find issues with the patch, let me know and I'll update it.