Clean up trailing and leading whitespace
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Within app/controllers/benefits_controller.rb:
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def upload
|
||||
<span style="background:yellow">file = params[:benefits][:upload]</span>
|
||||
@@ -46,7 +46,7 @@
|
||||
<span style="background:yellow">Benefits.save(file, params[:benefits][:backup])</span>
|
||||
else
|
||||
flash[:error] = "Something went wrong"
|
||||
end
|
||||
end
|
||||
redirect_to user_benefit_forms_path(:user_id => current_user.user_id)
|
||||
end
|
||||
</pre>
|
||||
@@ -71,11 +71,11 @@
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
</pre>
|
||||
|
||||
</pre>
|
||||
<p class="desc">
|
||||
The command injection vulnerability is introduced when the user-supplied input (name of file) is interpolated or mixed in with a system command.
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,7 +92,7 @@
|
||||
<p><b>Command Injection - ATTACK</b></p>
|
||||
<p class="desc">
|
||||
The filename portion of the benefits[upload] parameter is vulnerable to command injection. Navigate to the benefits section of the application, and choose a file to upload. Once the file is chosen, turn your intercepting proxy on, click start upload, and intercept the request. you will want to change the backup option to true (highlighted below) and inject your commands within the filename parameter (highlighted). Note: forward slashes ('/') are escaped by the original_filename method (used to extract the file name ).
|
||||
</p>
|
||||
</p>
|
||||
<pre class='ruby'>
|
||||
POST /upload HTTP/1.1
|
||||
Host: railsgoat.dev
|
||||
@@ -124,16 +124,16 @@
|
||||
</pre>
|
||||
<p><b>Command Injection - SOLUTION</b></p>
|
||||
<p class="desc">
|
||||
The solution is fairly simple and because this is so poorly done there are numerous ways to fix the vulnerability. One option, is to abstract a file creation method and pass it options such as the path and filename, then call it twice, once for the initial upload and another for the backup. Another option is to make a copy through the use of the FileUtils.
|
||||
The solution is fairly simple and because this is so poorly done there are numerous ways to fix the vulnerability. One option, is to abstract a file creation method and pass it options such as the path and filename, then call it twice, once for the initial upload and another for the backup. Another option is to make a copy through the use of the FileUtils.
|
||||
</p>
|
||||
<p>
|
||||
As an example:
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def self.make_backup(file, data_path, full_file_name)
|
||||
FileUtils.cp "#{full_file_name}", "#{data_path}/bak#{Time.now.to_i}_#{file.original_filename}"
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -150,7 +150,7 @@
|
||||
Let's create a backup when uploading a file, wonder how they are naming it?
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,7 +37,7 @@
|
||||
</p>
|
||||
<p>
|
||||
Within app/controllers/users_controller.rb
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def update
|
||||
message = false
|
||||
@@ -55,7 +55,7 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
The injection vulnerability is introduced when user-supplied input is placed within the SQL string that will be executed as a query. The application will not be able to determine which portion of this query is data and which portion is a query as the user input is interpolated or co-mingled with the query string.
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,7 +92,7 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Now we will inject some SQL Query syntax that will return the first result of a query that looks for users that have an admin attribute that is true. So essentially, instead of looking up the user whose data we will change by our user ID, we tell the database to return the first admin and update their data. In this instance, we are changing admin@metacorp.com's password to testtest. We can later login as that user. Granted, we could just change the user_id to 1 and do the same thing, and there are other ways to exploit this weakness but this is a clear-cut example of SQL Injection. <b> It is important to note that we have omitted the email, first, and last name parameters as a duplicate email address will cause errors. Additionally, we do not wish to change the admin's first and last name as this would alert the admin to the "hack".</b>
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
POST /users/5.json HTTP/1.1
|
||||
Host: railsgoat.dev
|
||||
@@ -110,7 +110,7 @@
|
||||
Cache-Control: no-cache
|
||||
|
||||
utf8=â&_method=put&authenticity_token=GXhLKKhfBXdFx5i6iqHEd5E32Kebn1+G35eA87RW1tU=&<span style="background:yellow">user[user_id]=5') OR admin = 't' --'")</span>&user[password]=testtest1&user[password_confirmation]=testtest1
|
||||
</pre>
|
||||
</pre>
|
||||
<p><b>SQL Injection - SOLUTION</b></p>
|
||||
<p class="desc">
|
||||
In this instance, the more secure route would be to reference the current_user object versus pulling from the database manually, using POST parameters provided by the user.<br/><br/>
|
||||
@@ -119,7 +119,7 @@
|
||||
def update
|
||||
message = false
|
||||
<span style="background-color:yellow">user = current_user</span>
|
||||
|
||||
|
||||
user.skip_user_id_assign = true
|
||||
user.update_attributes(params[:user].reject { |k| k == ("password" || "password_confirmation") || "user_id" })
|
||||
pass = params[:user][:password]
|
||||
@@ -136,7 +136,7 @@
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
user = User.find(:first, :conditions => ["user_id = ?", "#{params[:user][:user_id]}"])
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@
|
||||
I wonder who else's account needs updating?
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="widget">
|
||||
<div class="widget-header">
|
||||
<div class="title">
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span> A1 - SQL Injection - ActiveRecord Scope
|
||||
<span class="fs1" aria-hidden="true" data-icon=""></span> A1 - SQL Injection - ActiveRecord Scope
|
||||
</div>
|
||||
</div>
|
||||
<div class="widget-body">
|
||||
@@ -21,10 +21,10 @@
|
||||
</p>
|
||||
<pre><i>
|
||||
"Scoping allows you to specify commonly-used queries which can be referenced as <br/>method calls on the association objects or models."
|
||||
</i></pre>
|
||||
</i></pre>
|
||||
<p class="desc">
|
||||
This means that we can call a scope as a method and that the scope can be used for common queries such as <i>where</i> and <i>join</i>. Developers must be careful not to interpolate or concatenate user input into these scope calls as this can lead to SQL Injection. This is a common mistake made and can have serious consequences.
|
||||
</p>
|
||||
This means that we can call a scope as a method and that the scope can be used for common queries such as <i>where</i> and <i>join</i>. Developers must be careful not to interpolate or concatenate user input into these scope calls as this can lead to SQL Injection. This is a common mistake made and can have serious consequences.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,7 +53,7 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Additionally, within app/controllers/admin_controller.rb:
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def analytics
|
||||
if params[:field].nil?
|
||||
@@ -72,7 +72,7 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Within the controller we call the method <i>hits_by_ip</i>. This method is actually a scope as highlighted (above) in the Analytics model. The field object, defined within the controller, represents user-input that is intended to control the column returned by the SQL query. The field object represents the HTTP Request's parameter key. So this means we can control at least a portion of the query. Due to the fact that this input is used as an interpolated value within the query string, we have control over a larger portion of the query.
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,7 +89,7 @@
|
||||
<p><b>SQL Injection - ATTACK</b></p>
|
||||
<p class="desc">
|
||||
Navigate to the admin analytics panel. Send a request to search by an IP. Modify the request to change the parameter key to a partial SQL statement that returns all users and their information from the database:
|
||||
</p>
|
||||
</p>
|
||||
<pre>
|
||||
GET /admin/1/analytics?ip=127.0.0.1&field%5B*%20from%20users--%5D= HTTP/1.1
|
||||
Host: railsgoat.dev
|
||||
@@ -100,9 +100,9 @@
|
||||
Cookie:[redacted]
|
||||
Connection: keep-alive
|
||||
</pre>
|
||||
<p class="desc">
|
||||
<p class="desc">
|
||||
Essentially we are changing the intended SQL query from:
|
||||
</p>
|
||||
</p>
|
||||
<pre>
|
||||
SELECT <span style="background-color:yellow">UserInput</span> FROM "analytics" WHERE "analytics"."ip_address" = '127.0.0.1' ORDER BY id DESC
|
||||
</pre>
|
||||
@@ -111,11 +111,11 @@
|
||||
</p>
|
||||
<pre>
|
||||
SELECT * from users-- FROM "analytics" WHERE "analytics"."ip_address" = '127.0.0.1' ORDER BY id DESC
|
||||
</pre>
|
||||
</pre>
|
||||
<p><b>SQL Injection - SOLUTION</b></p>
|
||||
<p class="desc">
|
||||
To resolve this issue, do not interpolate user-provided input into SQL queries. However, it is always a good idea to create a whitelist of acceptable values when writing any code that is intended to be powerful and very flexible but that also leverages user-input to make these potentially security-impacting decisions. Within the Analytics model, we have a method called <i>parse_field</i>:
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def self.parse_field(field)
|
||||
valid_fields = ["ip_address", "referrer", "user_agent"]
|
||||
@@ -146,7 +146,7 @@
|
||||
render "layouts/admin/_analytics"
|
||||
end
|
||||
</pre>
|
||||
<p class="desc">
|
||||
<p class="desc">
|
||||
Effectively, we've changed any malicious data provided by the user into the number '1' by leveraging the above code.
|
||||
</p>
|
||||
</div>
|
||||
@@ -165,7 +165,7 @@
|
||||
Administrative analytics functionality need further security analysis. Now might be a good time to test for SQLi.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user