I am running into a weird CSRF where I am trying to access a javascript file uploaded on my rails server. I have a controller such as:
class SomeController < ApplicationController
def show
some_path = "/some/js/file/on/disk.js"
send_file(some_path, type: "text/javascript", disposition: :inline)
end
end
However when navigating to http://localhost:3000/somes/1
I get the error message:
Security warning: an embedded tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
Extracted source (around line #225):
if marked_for_same_origin_verification? && non_xhr_javascript_response? logger.warn CROSS_ORIGIN_JAVASCRIPT_WARNING if logger raise ActionController::InvalidCrossOriginRequest, CROSS_ORIGIN_JAVASCRIPT_WARNING end end
Note that I am accessing this page directly which means that there is no layout so I cannot include a CSRF token in my layout.
Is there something that needs to be done differently to correctly access this resource?
EDIT: Per comment request, I have added the Full Trace below.
actionpack (4.2.6) lib/action_controller/metal/request_forgery_protection.rb:225:in
verify_same_origin_request' activesupport (4.2.6) lib/active_support/callbacks.rb:432:in
block in make_lambda' activesupport (4.2.6) lib/active_support/callbacks.rb:239:inblock in halting' activesupport (4.2.6) lib/active_support/callbacks.rb:506:in
block in call' activesupport (4.2.6) lib/active_support/callbacks.rb:506:ineach' activesupport (4.2.6) lib/active_support/callbacks.rb:506:in
call' activesupport (4.2.6) lib/active_support/callbacks.rb:92:in__run_callbacks__' activesupport (4.2.6) lib/active_support/callbacks.rb:778:in
_run_process_action_callbacks' activesupport (4.2.6) lib/active_support/callbacks.rb:81:inrun_callbacks' actionpack (4.2.6) lib/abstract_controller/callbacks.rb:19:in
process_action' actionpack (4.2.6) lib/action_controller/metal/rescue.rb:29:inprocess_action' actionpack (4.2.6) lib/action_controller/metal/instrumentation.rb:32:in
block in process_action' activesupport (4.2.6) lib/active_support/notifications.rb:164:inblock in instrument' activesupport (4.2.6) lib/active_support/notifications/instrumenter.rb:20:in
instrument' activesupport (4.2.6) lib/active_support/notifications.rb:164:ininstrument' actionpack (4.2.6) lib/action_controller/metal/instrumentation.rb:30:in
process_action' actionpack (4.2.6) lib/action_controller/metal/params_wrapper.rb:250:inprocess_action' activerecord (4.2.6) lib/active_record/railties/controller_runtime.rb:18:in
process_action' actionpack (4.2.6) lib/abstract_controller/base.rb:137:inprocess' actionview (4.2.6) lib/action_view/rendering.rb:30:in
process' actionpack (4.2.6) lib/action_controller/metal.rb:196:indispatch' actionpack (4.2.6) lib/action_controller/metal/rack_delegation.rb:13:in
dispatch' actionpack (4.2.6) lib/action_controller/metal.rb:237:inblock in action' actionpack (4.2.6) lib/action_dispatch/routing/route_set.rb:74:in
dispatch' actionpack (4.2.6) lib/action_dispatch/routing/route_set.rb:43:inserve' actionpack (4.2.6) lib/action_dispatch/journey/router.rb:43:in
block in serve' actionpack (4.2.6) lib/action_dispatch/journey/router.rb:30:ineach' actionpack (4.2.6) lib/action_dispatch/journey/router.rb:30:in
serve' actionpack (4.2.6) lib/action_dispatch/routing/route_set.rb:817:incall' bullet (5.1.1) lib/bullet/rack.rb:12:in
call' warden (1.2.6) lib/warden/manager.rb:35:inblock in call' warden (1.2.6) lib/warden/manager.rb:34:in
catch' warden (1.2.6) lib/warden/manager.rb:34:incall' rack (1.6.4) lib/rack/etag.rb:24:in
call' rack (1.6.4) lib/rack/conditionalget.rb:25:incall' rack (1.6.4) lib/rack/head.rb:13:in
call' actionpack (4.2.6) lib/action_dispatch/middleware/params_parser.rb:27:incall' actionpack (4.2.6) lib/action_dispatch/middleware/flash.rb:260:in
call' rack (1.6.4) lib/rack/session/abstract/id.rb:225:incontext' rack (1.6.4) lib/rack/session/abstract/id.rb:220:in
call' actionpack (4.2.6) lib/action_dispatch/middleware/cookies.rb:560:incall' activerecord (4.2.6) lib/active_record/query_cache.rb:36:in
call' activerecord (4.2.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:incall' activerecord (4.2.6) lib/active_record/migration.rb:377:in
call' actionpack (4.2.6) lib/action_dispatch/middleware/callbacks.rb:29:inblock in call' activesupport (4.2.6) lib/active_support/callbacks.rb:88:in
run_callbacks' activesupport (4.2.6) lib/active_support/callbacks.rb:778:in_run_call_callbacks' activesupport (4.2.6) lib/active_support/callbacks.rb:81:in
run_callbacks' actionpack (4.2.6) lib/action_dispatch/middleware/callbacks.rb:27:incall' actionpack (4.2.6) lib/action_dispatch/middleware/reloader.rb:73:in
call' actionpack (4.2.6) lib/action_dispatch/middleware/remote_ip.rb:78:incall' actionpack (4.2.6) lib/action_dispatch/middleware/debug_exceptions.rb:17:in
call' web-console (2.3.0) lib/web_console/middleware.rb:28:inblock in call' web-console (2.3.0) lib/web_console/middleware.rb:18:in
catch' web-console (2.3.0) lib/web_console/middleware.rb:18:incall' actionpack (4.2.6) lib/action_dispatch/middleware/show_exceptions.rb:30:in
call' railties (4.2.6) lib/rails/rack/logger.rb:38:incall_app' railties (4.2.6) lib/rails/rack/logger.rb:20:in
block in call' activesupport (4.2.6) lib/active_support/tagged_logging.rb:68:inblock in tagged' activesupport (4.2.6) lib/active_support/tagged_logging.rb:26:in
tagged' activesupport (4.2.6) lib/active_support/tagged_logging.rb:68:intagged' railties (4.2.6) lib/rails/rack/logger.rb:20:in
call' quiet_assets (1.1.0) lib/quiet_assets.rb:27:incall_with_quiet_assets' request_store (1.3.1) lib/request_store/middleware.rb:9:in
call' actionpack (4.2.6) lib/action_dispatch/middleware/request_id.rb:21:incall' rack (1.6.4) lib/rack/methodoverride.rb:22:in
call' rack (1.6.4) lib/rack/runtime.rb:18:incall' activesupport (4.2.6) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in
call' rack (1.6.4) lib/rack/lock.rb:17:incall' actionpack (4.2.6) lib/action_dispatch/middleware/static.rb:120:in
call' rack (1.6.4) lib/rack/sendfile.rb:113:incall' railties (4.2.6) lib/rails/engine.rb:518:in
call' railties (4.2.6) lib/rails/application.rb:165:incall' rack (1.6.4) lib/rack/content_length.rb:15:in
call' puma (3.5.0) lib/puma/configuration.rb:225:incall' puma (3.5.0) lib/puma/server.rb:569:in
handle_request' puma (3.5.0) lib/puma/server.rb:406:inprocess_client' puma (3.5.0) lib/puma/server.rb:271:in
block in run' puma (3.5.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'
Briefly, Cross-Site Request Forgery (CSRF) is an attack that allows a malicious user to spoof legitimate requests to your server, masquerading as an authenticated user. Rails protects against this kind of attack by generating unique tokens and validating their authenticity with each submission.
The server generates these tokens, links them to the user session, and stores them in the database. This token is then injected into any form presented to the client as a hidden field. When the client correctly submits the form for validation, it passes the token back to the server.
verify_authenticity_token() private. The actual before_action that is used to verify the CSRF token.
As error message says, you need to disable forgery protection for this action.
class SomeController < ApplicationController
skip_before_action :verify_authenticity_token, only: :show
def show
some_path = "/some/js/file/on/disk.js"
send_file(some_path, type: "text/javascript", disposition: :inline)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With