I am trying to configure a classic Sinatra 2.0.8.1 app ("www.example.com") to use Rack::Protection
, and especially Rack::Protection::AuthenticityToken
, on some but not all routes.
Internal forms (within the app) work fine. Each form has a hidden CSRF authenticity token, so the forms in the app can POST data to routes in the app.
However I cannot find any documentation how to EXCEPT or SKIP AuthenticityToken for certain routes so that external apps can POST data to this app.
In this case we have a few routes to which two of our other apps ('foo.example.com' and 'bar.example.com') POST data to. But when we implemented Rack::Protection::AuthenticityToken
all of those routes now return a 403 when posted to.
I've tried a variety of things such as permitted_origins
and origin_whitelist
as shown below, but no external app can POST data to the Sinatra app unless I disable Rack::Protection::AuthenticityToken
for the entire app.
# foo.example.com
# doesnt work:
require 'rack/protection'
use Rack::Protection, permitted_origins: ["https://foo.example.com", "https://bar.example.com"]
set :protection, :origin_whitelist => ['https://foo.example.com', 'https://bar.example.com'], except: [:remote_token, :frame_options, :path_traversal]
use Rack::Protection::AuthenticityToken
use Rack::Protection::RemoteReferrer
Surely there is some mechanism for "omitting" the requirement for a CSRF token on certain routes, such as api routes that receive POSTed data?
Although the solution makes me feel dirty, here's what worked:
put all routes in their own file/class (kind of like controllers in Rails)
the (api) routes that I wanted to NOT use a CSRF token, I
use
THAT class file before I do the Rack protection initializations.The classes containing the (normal) routes I DO want to protect from CSRF gets
use
after the Rackprotection initialization.