问题描述
我正在尝试将经典的Sinatra 2.0.8.1应用程序(“ www.example.com”)配置为在部分但并非全部路径上使用Rack::Protection
,尤其是Rack::Protection::AuthenticityToken
。
内部表单(在应用内)可以正常工作。每个表单都有一个隐藏的CSRF真实性令牌,因此应用程序 in 中的表单可以将数据发布到应用程序 in 中的路由。
但是我找不到任何文档来了解某些路由如何超越或跳过AuthenticityToken,以便外部应用可以将数据发布到该应用。
在这种情况下,我们有两个其他应用程序(“ foo.example.com”和“ bar.example.com”)将数据发布到的路由。但是,当我们实现Rack::Protection::AuthenticityToken
时,所有这些路由在发布到时都会返回403。
我已经尝试了诸如permitted_origins
和origin_whitelist
之类的各种操作,如下所示,但是除非我整个禁用Rack::Protection::AuthenticityToken
,否则任何外部应用都无法将数据发布到Sinatra应用中应用程序。
# 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
是否确实有 some 机制可以“忽略”某些路由(例如接收POST数据的api路由)对CSRF令牌的要求?
解决方法
尽管解决方案使我感到肮脏,但这是可行的:
-
将所有路由放入自己的文件/类(类似于Rails中的控制器)
-
我不希望使用CSRF令牌的(api)路由,在进行机架保护初始化之前,我
use
该类文件。 -
在Rackprotection初始化之后,包含我想从CSRF保护的(普通)路由的类在{em> 之后得到
use
。
use Rack::Protection
set :protection,except: [:path_traversal]
# FIRST LOAD ROUTES *NOT* PROTECTED BY Rack::Protection::AuthenticityToken
use ApplicationController
use ApipostController # external POST routes to omit
# NOW enable the AuthenticityToken protection
Rack::Protection::AuthenticityToken
use Rack::Protection::AuthenticityToken
use Rack::Protection::RemoteReferrer
# now LOAD NORMAL ROUTES TO BE PROTECTED BY Rack::Protection::AuthenticityToken
use FooController
use BarController