Convert file indentation to spaces
This commit is contained in:
@@ -17,8 +17,8 @@
|
||||
<div class="accordion-body in collapse" id="collapseOne" style="height: auto;">
|
||||
<div class="accordion-inner">
|
||||
<p class="desc">
|
||||
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.
|
||||
</p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,22 +33,22 @@
|
||||
<div class="accordion-body collapse" id="collapseTwo" style="height: 0px;">
|
||||
<div class="accordion-inner">
|
||||
<p>
|
||||
Within the file app/controllers/benefit_forms_controller.rb:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def download
|
||||
begin
|
||||
<span style="background-color:yellow">path = Rails.root.join('public', 'docs', params[:name])</span>
|
||||
<span style="background-color:yellow">file = params[:type].constantize.new(path)</span>
|
||||
send_file file, :disposition => 'attachment'
|
||||
rescue
|
||||
redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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. Additionally, the params[:type] (File) is not validated to make sure it matches up with expected values.
|
||||
</p>
|
||||
Within the file app/controllers/benefit_forms_controller.rb:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def download
|
||||
begin
|
||||
<span style="background-color:yellow">path = Rails.root.join('public', 'docs', params[:name])</span>
|
||||
<span style="background-color:yellow">file = params[:type].constantize.new(path)</span>
|
||||
send_file file, :disposition => 'attachment'
|
||||
rescue
|
||||
redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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. Additionally, the params[:type] (File) is not validated to make sure it matches up with expected values.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,55 +63,55 @@
|
||||
<div class="accordion-body collapse" id="collapseThree" style="height: 0px;">
|
||||
<div class="accordion-inner">
|
||||
<p><b> Constantize ATTACK:</b></p>
|
||||
<p class="desc">
|
||||
In order to attack this weakness, navigate to the benefit forms page and observe the link to download either the health or dental documents.
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
http://railsgoat.dev/download?name=Health_n_Stuff.pdf&type=File
|
||||
</pre>
|
||||
<p>
|
||||
Change the name parameter to something a little more fun like:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
http://railsgoat.dev/download?name=../../config/initializers/secret_token.rb&type=File
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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.<br/><br/> Example:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
../../../../../../../etc/passwd&type=File
|
||||
</pre>
|
||||
<p><b> Constantize SOLUTION:</b></p>
|
||||
<p class="desc">
|
||||
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:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
# More secure version
|
||||
def download
|
||||
<span style="background-color:yellow">file_assoc = {"1" => "Health_n_Stuff.pdf", "2" => "Dental_n_Stuff.pdf"}</span>
|
||||
begin
|
||||
<span style="background-color:yellow">if file_assoc.has_key?(params[:name].to_s)</span>
|
||||
path = Rails.root.join('public', 'docs', file_assoc[params[:name].to_s])
|
||||
<span style="background-color:yellow">if params[:type] == "File"</span>
|
||||
file = params[:type].constantize.new(path)
|
||||
send_file file, :disposition => 'attachment'
|
||||
end
|
||||
else
|
||||
file = Rails.root.join('public', 'docs', "Dental_n_Stuff.pdf")
|
||||
send_file file, :disposition => 'attachment'
|
||||
end
|
||||
rescue
|
||||
redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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.
|
||||
</p>
|
||||
<p class="desc">
|
||||
In order to attack this weakness, navigate to the benefit forms page and observe the link to download either the health or dental documents.
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
http://railsgoat.dev/download?name=Health_n_Stuff.pdf&type=File
|
||||
</pre>
|
||||
<p>
|
||||
Change the name parameter to something a little more fun like:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
http://railsgoat.dev/download?name=../../config/initializers/secret_token.rb&type=File
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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.<br/><br/> Example:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
../../../../../../../etc/passwd&type=File
|
||||
</pre>
|
||||
<p><b> Constantize SOLUTION:</b></p>
|
||||
<p class="desc">
|
||||
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:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
# More secure version
|
||||
def download
|
||||
<span style="background-color:yellow">file_assoc = {"1" => "Health_n_Stuff.pdf", "2" => "Dental_n_Stuff.pdf"}</span>
|
||||
begin
|
||||
<span style="background-color:yellow">if file_assoc.has_key?(params[:name].to_s)</span>
|
||||
path = Rails.root.join('public', 'docs', file_assoc[params[:name].to_s])
|
||||
<span style="background-color:yellow">if params[:type] == "File"</span>
|
||||
file = params[:type].constantize.new(path)
|
||||
send_file file, :disposition => 'attachment'
|
||||
end
|
||||
else
|
||||
file = Rails.root.join('public', 'docs', "Dental_n_Stuff.pdf")
|
||||
send_file file, :disposition => 'attachment'
|
||||
end
|
||||
rescue
|
||||
redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<p class="desc">
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-group">
|
||||
<div class="accordion-group">
|
||||
<div class="accordion-heading">
|
||||
<a style="background-color: rgb(181, 121, 158)" href="#collapseFour" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
|
||||
<i class="icon-aid icon-white">
|
||||
@@ -125,6 +125,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user