CVE-2021-43846 (published 2021-12-20T22:15Z)

`solidus_frontend` is the cart and storefront for the Solidus e-commerce project. Versions of `solidus_frontend` prior to 3.1.5, 3.0.5, and 2.11.14 contain a cross-site request forgery (CSRF) vulnerability that allows a malicious site to add an item to the user\'s cart without their knowledge. Versions 3.1.5, 3.0.5, and 2.11.14 contain a patch for this issue. The patch adds CSRF token verification to the "Add to cart" action. Adding forgery protection to a form that missed it can have some side effects. Other CSRF protection strategies as well as a workaround involving modifcation to config/application.rb` are available. More details on these mitigations are available in the GitHub Security Advisory.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:P/A:N)
CVSS v3 base score: 4.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/solidusio/solidus
commit_details: repo_url: https://github.com/solidusio/solidus
author: Marc Busqué
author_date: 2021-12-14 10:36:44+01:00
msg: Protect `Spree::OrdersController#populate` against CSRF attacks

See
https://github.com/solidusio/solidus/security/advisories/GHSA-h3fg-h5v3-vf8m
for all the details.

Some time ago, all order actions were left out of CSRF protection (see
95ea57058ab1c5e722b327b10747cd41e68a4deb). The reason given was that the
authentication token got stale after the second rendering because the
product page is cached. That was limited to `#populate` in
cb797542c6948ef33d2cc9e6076c88f4cc927fb2 (see also
https://github.com/spree/spree/pull/5601).

However, those assumptions are not correct. Although the authenticity
token changes at every request, that doesn't mean that the old ones are
no longer valid. The variation comes from a one-time pad added to a
session-dependant token (and meant to avoid timing attacks). However,
before validation, that one-time pad is removed. That means the token
remains valid as long as the session has not been reset. Think about
submitting a form from one browser tab after opening another with the
same URL. Even if both tokens differ, the submission from the first tab
will still be valid. You can read
https://medium.com/rubyinside/a-deep-dive-into-csrf-protection-in-rails-19fa0a42c0ef
for an in-deep understanding.

The initial confusion could come because of
https://github.com/rails/rails/issues/21948. Due to browser-side cache,
a form can be re-rendered and sent without any attached request cookie.
That will cause an authentication error, as the sent token won't match
with the one in the session (none in this case). There's no perfect
solution for that, and all partial fixes should be seen at the
application level. From our side, we must provide a safe default. For an
excellent survey of all the available options, take a look at
https://github.com/betagouv/demarches-simplifiees.fr/blob/5b4f7f9ae9eaf0ac94008b62f7047e4714626cf9/doc/adr-csrf-forgery.md.
The information given in that link is third-party but it's very
relevant here. For that reason we've copied it in the security advisory
(see link above), but all the credit goes to @kemenaran.
repository: repo_url: https://github.com/solidusio/solidus
repo_name: solidusio/solidus
description: 🛒 Solidus, the open-source eCommerce framework for industry trailblazers.
repo_language: Ruby
owner: solidusio
file_changes: filename: orders_controller.rb
change_type: ModificationType.MODIFY
diff: @@ -10,7 +10,6 @@ module Spree
     before_action :assign_order, only: :update
     # note: do not lock the #edit action because that's where we redirect when we fail to acquire a lock
     around_action :lock_order, only: :update
-    skip_before_action :verify_authenticity_token, only: [:populate]
 
     def show
       @order = Spree::Order.find_by!(number: params[:id])

programming_language: Ruby
repo_url: https://github.com/solidusio/solidus
commit_details: repo_url: https://github.com/solidusio/solidus
author: Marc Busqué
author_date: 2021-12-20 09:25:33+01:00
msg: Merge pull request from GHSA-h3fg-h5v3-vf8m

Protect `Spree::OrdersController#populate` against CSRF attacks
repository: repo_url: https://github.com/solidusio/solidus
repo_name: solidusio/solidus
description: 🛒 Solidus, the open-source eCommerce framework for industry trailblazers.
repo_language: Ruby
owner: solidusio