DEV Community

Cover image for Securing Rails Active Storage Direct Uploads
Given Ncube
Given Ncube

Posted on • Originally published at givenis.me

Securing Rails Active Storage Direct Uploads

TL;DR; if you just want the code, head over to the bottom of this article

I noticed something odd with Active Storage direct uploads. Did you know there is literally no authentication at all by default! The idea scared me.

From the docs, it doesn’t say how to secure that endpoint either. There’s a way to use token auth for API apps but for traditional apps that’s still pretty much open season.

Let’s look at how that can be problematic, First we have CSRF protection so no one can just fire up curl and start uploading files from a script, however that can be easily solved by first making a legit request, grabbing the CSRF token and voila! We also have security by obfuscation assuming that a malicious actor doesn’t know that active storage uploads exists but I’m sure they can read the same documentation that you and I know read.

Someone can just spam upload large files and offset your S3 bill or simply run you out of storage, or DDOS your server all of which are not desirable scenarios.

To solve, this I found some GitHub issues that discussed this but no one provided a solution for what I was worried about, I saw an article from this guy but his solution suggested extending the ActiveStorge::DirectUploadsController and creating a new route. This doesn’t really solve the problem because the other active storage direct uploads route will still be unprotected, I took his solution and used a much simpler implementation using an initializer.

Basically, we want

  • authenticate the direct uploads endpoint with a before_action

  • rate limit the endpoint to prevent DDOS

# config/initializers/active_storage.rb
Rails.application.config.to_prepare do
  ActiveStorage::DirectUploadsController.class_eval do
    before_action :authenticate_user!
    rate_limit to: 20, within: 20.minutes, by: -> { current_user.id }
  end
end
Enter fullscreen mode Exit fullscreen mode

Rails has a configuration hook, at least that’s what I think that is, that allows you to run code before the rails app boots I imagine. The cool thing is, we can do a class_eval on the ActiveStorage::DirectUploadsController to add a before_action to authenticate the user then rate limit by user id so that one user doesn’t just spam upload files to the server.

Top comments (2)

Collapse
 
j_potter_3434 profile image
John Potter

It would be nice to show error message to the user without a page redirect.

Collapse
 
slimgee profile image
Given Ncube

It's possible, with direct uploads, and stimulus you can show errors, I'm using this with dropzone