Insecure File Management

Why is this important?

Any functionality related to file management requires careful usage. If attackers are able to influence the input to file access related APIs, then it can have a serious impact. For example, attackers could read the all files on your application server.

In other cases, this can allow attackers to include their own code, or files, that are then executed by the application at runtime.

Check out this video for a high-level explanation on local file inclusion issues:

Local File Inclusion

Another high-level explanation on remote file inclusion issues:

Remote File Inclusion

Fixing Insecure File Management

Option A: Migrate to Active Storage

  1. Nowadays, there is rarely a need to allow users to interact with local files.
  2. A better alternative is storing files in dedicated systems, such as AWS S3.
  3. Ruby on Rails 5.2 ships with Active Storage, which exposes cloud storage services.
  4. More information on Active Storage can be found here.

Option B: Sanitize Input

  1. Go through the issues that GuardRails identified in the PR.
  2. A vulnerable example is shown below:

     def download
         language_code = params[:code]
         send_file(
         "#{Rails.root}/config/locales/#{language_code}.yml",
         filename: "#{language_code}.yml",
         type: "application/yml"
         )
     end
    
  3. Replace it with the following pattern:

     def sanitize(filename)
         # Remove any character that aren't 0-9, A-Z, or a-z
         filename.gsub(/[^0-9A-Z]/i, '_')
     end
    
     def download
         language_code = params[:code]
         send_file(
         "#{Rails.root}/config/locales/#{language_code}.yml",
         filename: "#{sanitize(language_code)}.yml",
         type: "application/yml"
         )
     end
    
  4. Test it

  5. Ship it 🚢 and relax 🌴

More information: