From 88ea613da6df21788c40e90cf8837eb29423d2fe Mon Sep 17 00:00:00 2001 From: Ken Johnson Date: Sun, 2 Jun 2013 23:32:37 -0400 Subject: [PATCH] okay, write-up finished --- app/controllers/benefit_forms_controller.rb | 17 +++ .../_benefit_forms_constantize.html.erb | 125 ++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/app/controllers/benefit_forms_controller.rb b/app/controllers/benefit_forms_controller.rb index bac8b7f..5684bcf 100644 --- a/app/controllers/benefit_forms_controller.rb +++ b/app/controllers/benefit_forms_controller.rb @@ -12,4 +12,21 @@ class BenefitFormsController < ApplicationController end end +=begin + # More secure version + def download + file_assoc = {"1" => "Health_n_Stuff.pdf", "2" => "Dental_n_Stuff.pdf"} + begin + if file_assoc.has_key?(params[:name].to_s) + file = Rails.root.join('public', 'docs', file_assoc[params[:name].to_s]) + send_file file, :disposition => 'attachment' + else + file = Rails.root.join('public', 'docs', "Dental_n_Stuff.pdf") + end + rescue + redirect_to user_benefit_forms_path(:user_id => current_user.user_id) + end + end +=end + end diff --git a/app/views/layouts/tutorial/constantize/_benefit_forms_constantize.html.erb b/app/views/layouts/tutorial/constantize/_benefit_forms_constantize.html.erb index e69de29..41a59f0 100644 --- a/app/views/layouts/tutorial/constantize/_benefit_forms_constantize.html.erb +++ b/app/views/layouts/tutorial/constantize/_benefit_forms_constantize.html.erb @@ -0,0 +1,125 @@ +
+
+
+ Constantize +
+
+
+
+
+ +
+
+

+ The constantize method is a Rails MetaProgramming method designed to dynamically find a constant that matches the string specified. This is often used to dynamically instantiate a class or module. When user-supplied input is a part of that equation, great precautions must be taken to ensure security holes are not introduced. +

+
+
+
+
+ +
+
+

+ Within the file app/controllers/benefit_forms_controller.rb: +

+
+				  def download
+				   begin  
+				     file = Rails.root.join('public', 'docs', params[:name])
+				     send_file file, :disposition => 'attachment'
+				   rescue
+				     redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
+				   end
+				  end
+			  
+

+ The location of the file to render is dynamically generated based on user input (params[:name]). This means the user controls the location of the file to be retrieved. +

+
+
+
+
+ +
+
+

Constantize ATTACK:

+

+ In order to attack this weakness, navigate to the benefit forms page and observe the link to download either the health or dental documents. +

+
+				 http://railsgoat.dev/download?name=Health_n_Stuff.pdf&type=File
+			   
+

+ Change the name parameter to something a little more fun like: +

+
+			 		http://railsgoat.dev/download?name=../../config/initializers/secret_token.rb&type=File
+				
+

+ This second request string specifies to navigate back two directories and then look for config/intiializers/secret_token.rb. It is important to note, even when Rails.root.join is used, leveraging path traversal (ex: ../../) allows the attacker to retrieve any file that the application's user has permissions to.

Example: +

+
+					../../../../../../../etc/passwd&type=File
+				
+

Constantize SOLUTION:

+

+ In this instance and as always, there are multiple ways to fix this. A simple method to secure this function by validating user input is as follows: +

+
+					 # More secure version
+				    def download
+				     file_assoc = {"1" => "Health_n_Stuff.pdf", "2" => "Dental_n_Stuff.pdf"}
+				     begin  
+				       if file_assoc.has_key?(params[:name].to_s)
+				          file = Rails.root.join('public', 'docs', file_assoc[params[:name].to_s])
+				          send_file file, :disposition => 'attachment'
+				       else 
+				         file =  Rails.root.join('public', 'docs', "Dental_n_Stuff.pdf")
+				       end
+				     rescue
+				       redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
+				     end
+				    end
+				
+

+ The fix ultimately boils down to leveraging a hash, if the hash has the key provided by the user, the value associated with that key is the name of the file to be returned. +

+
+
+
+
+ +
+
+ It can be very helpful for employees to download benefit forms. +
+
+
+
+
+
\ No newline at end of file