Giter Club home page Giter Club logo

paperclip-nginx-upload's Introduction

Paperclip Nginx Upload

Gem Version Build Status

A Paperclip IOAdapter to handle file upload requests which have been rewritten by the nginx upload module.

The gem evolved out of the discussion in the following paperclip issue: thoughtbot/paperclip#1396

Motivation

Nginx is much faster when it comes to parsing file uploads from the body of HTTP requests. We do not want to occupy our Rails processes with this tasks. Using the nginx upload module, upload request can be rewritten to contain the path of a temp file parsed from the request body before they are passed to our Rails app.

Installation

Choose one from two options and add line to your application's Gemfile:

1.) with paperclip dependency, use:

gem 'paperclip-nginx-upload', '~> 1.0'

2.) with kt-paperclip dependency, use:

gem 'paperclip-nginx-upload', '~> 2.0'

Usage

Configure nginx to parse your upload requests. There is an example nginx configuration snippet in examples/nginx.conf.

Add an initializer to configure the gem:

 # config/intializers/paperclip_nginx_upload.rb
 require 'paperclip/nginx/upload'

 Paperclip::Nginx::Upload::IOAdapter.default_options.merge!(
   # location where nginx places file uploads
   tmp_path_whitelist: ['/tmp/nginx_uploads/**'],

   # Change this option to true to move temp files created
   # by nginx to the paperclip tmp file location. By default
   # files are copied.
   move_tempfile: false
 )

The adapter is a drop in replacement. When using strong parameters, you only have to make sure the param containing the upload can also be a hash of values:

 class User
   has_attached_file :avatar
 end

 class UsersController < ApplicationController
   def update
     @user.update_attributes(user_params)
   end

   def user_params
     params.require(:user)
      # in production avatar will be a hash generated by nginx
      .permit(avatar: [:tmp_path, :original_name, :content_type])

      # in development we want to permit the uploaded file itself
      .merge(params.require(:user).permit(:avatar))
   end
 end

Security Considerations

Assume an upload request contains a form field named user[avatar]. Given the nginx configuration from examples/nginx.conf, the request is rewritten to contain the following three form fields instead:

  • user[avatar][original_name]
  • user[avatar][conten_type]
  • user[avatar][tmp_path]

By using this gem, you basically tell your app to accept paths to local files in the tmp_path param and move them around the file system. Nginx ensures that these parameters can not be passed in from the outside, preventing an attacker from passing /etc/passwd as tmp_path and having it delivered to him as his own upload later on.

Still, if you forget to configure the nginx-upload-module correctly for one of your upload end points, this could become a threat. This is especially dangerous when not using strong parameters. While, as seen above, the nested hash has to be permitted explicitly, methods assigning attachments directly might be open to attacks:

 @user.avatar = params[:avatar]

Therefore the paperclip-nginx-upload adapter only accepts tmp files from locations matching an entry in the tmp_path_whitelist. That way an attacker will only be able to access running uploads of other visitors of the site. He still would have to guess the random file names chosen by nginx, which seems rather unfeasable.

Move vs Copy

By default, temp files created by ngninx are copied before passing them to Paperclip. This ensures proper file ownership. When your nginx runs as the same user as your rails processes, it might be sufficient to simply move the file. Depending on your file system, this might be a significant performance gain. In that case set move_tempfile to true.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

paperclip-nginx-upload's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

paperclip-nginx-upload's Issues

Paperclip deprecated

Hello, as original project is deprecated, but continue to live on different gem kt-paperclip, would it be possible to update yours gem dependency to it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.