Clean up trailing and leading whitespace
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
The above two lines specify that we will run these validations prior to allowing a user to interact with the API endpoints.
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def valid_api_token
|
||||
authenticate_or_request_with_http_token do |token, options|
|
||||
@@ -49,7 +49,7 @@
|
||||
identify_user(token)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def identify_user(token="")
|
||||
# We've had issues with URL encoding, etc. causing issues so just to be safe
|
||||
# we will go ahead and unescape the user's token
|
||||
@@ -60,12 +60,12 @@
|
||||
(id && hash) ? true : false
|
||||
<span style="background-color:yellow">check_hash(id, hash) ? true : false</span>
|
||||
end
|
||||
|
||||
|
||||
def check_hash(id, hash)
|
||||
<span style="background-color:yellow">digest = OpenSSL::Digest::SHA1.hexdigest("#{ACCESS_TOKEN_SALT}:#{id}")</span>
|
||||
hash == digest
|
||||
hash == digest
|
||||
end
|
||||
|
||||
|
||||
# We had some issues with the token and url encoding...
|
||||
# this is an attempt to normalize the data.
|
||||
def unescape_token(token="")
|
||||
@@ -80,22 +80,22 @@
|
||||
def extrapolate_user
|
||||
<span style="background-color:yellow">@user = User.find_by_id(@clean_token.split("-").first)</span>
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Unfortunately, we've made a mistake. The regular expression can be bypassed by entering a newline character (url encoded: <i>%0a</i>).We meant or expected for a user to enter a token such as:
|
||||
</p>
|
||||
<pre>
|
||||
Authorization: Token token=1-01de24d75cffaa66db205278d1cf900bf087a737
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
However, the user actually enters:
|
||||
</p>
|
||||
<pre>
|
||||
Authorization: Token token=2%0a1-01de24d75cffaa66db205278d1cf900bf087a737
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
This means that our token will pass the initial hash check. Additionally, when we perform the split by the hyphen (<i>"-"</i>) character, and retrieve the first value from the newly created array (what should be a valid user ID), it will be <i>"2\n1"</i>. When performing a <i>find_by_*</i>, ActiveRecord will ignore everything from the newline character on and return the result of the first character. This means, we can become another user!
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,7 +111,7 @@
|
||||
<div class="accordion-inner">
|
||||
<p><b> Broken Regular Expression ATTACK:</b></p>
|
||||
<p class="desc">
|
||||
As discussed in the Bug Section (above), you can prepend the user ID of the person whose information you would like to retrieve followed by a newline character and your user's valid API token. The following is an example of what our request <i>should</i> look like:
|
||||
As discussed in the Bug Section (above), you can prepend the user ID of the person whose information you would like to retrieve followed by a newline character and your user's valid API token. The following is an example of what our request <i>should</i> look like:
|
||||
</p>
|
||||
<pre>
|
||||
GET /api/v1/users HTTP/1.1
|
||||
@@ -120,7 +120,7 @@
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
Accept-Language: en-US,en;q=0.5
|
||||
Accept-Encoding: gzip, deflate
|
||||
<span style="background-color:yellow">Authorization: Token token=2-050ddd40584978fe9e82840b8b95abb98e4786dc</span>
|
||||
<span style="background-color:yellow">Authorization: Token token=2-050ddd40584978fe9e82840b8b95abb98e4786dc</span>
|
||||
Content-Length: 4
|
||||
</pre>
|
||||
<p class="desc">
|
||||
@@ -135,11 +135,11 @@
|
||||
X-Request-Id: 0ef6e5e91730bfecb9711c0ddad5cc7b
|
||||
X-Runtime: 0.008342
|
||||
Connection: close
|
||||
|
||||
|
||||
{"admin":false,"created_at":"2014-01-23T16:17:10Z","email":"jack@metacorp.com",
|
||||
"first_name":"Jack","id":2,"last_name":"Mannino","password":"b46dd2888a0904972649cc880a93f4dd",
|
||||
"updated_at":"2014-01-23T16:17:10Z","user_id":2}
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
We want to access this endpoint as an admin (user ID of 1). We will change our request so that we can emulate <b>being</b> and admin by prepending 1%0a:
|
||||
</p>
|
||||
@@ -150,12 +150,12 @@
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
Accept-Language: en-US,en;q=0.5
|
||||
Accept-Encoding: gzip, deflate
|
||||
Authorization: Token token=<span style="background-color:yellow">1%0a</span>2-050ddd40584978fe9e82840b8b95abb98e4786dc
|
||||
Content-Length: 4
|
||||
Authorization: Token token=<span style="background-color:yellow">1%0a</span>2-050ddd40584978fe9e82840b8b95abb98e4786dc
|
||||
Content-Length: 4
|
||||
</pre>
|
||||
<p class="desc">
|
||||
The following is a response from the application (note - we get bonus points because as an admin we can retrieve <b> EVERYONE's</b> data):
|
||||
</p>
|
||||
</p>
|
||||
<pre>
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
@@ -165,7 +165,7 @@
|
||||
X-Request-Id: e56b6bc1c6d6b875249f6d27b9f9450c
|
||||
X-Runtime: 0.009111
|
||||
Connection: close
|
||||
|
||||
|
||||
[{"admin":true,"created_at":"2014-01-23T16:17:10Z","email":"admin@metacorp.com","first_name":
|
||||
"Admin","id":1,"last_name":"","password":"c93ccd78b2076528346216b3b2f701e6","updated_at":"2014-01-23T16:17:10Z","user_id":1},
|
||||
{"admin":false,"created_at":"2014-01-23T16:17:10Z","email":"jack@metacorp.com","first_name":"Jack","id":2,"last_name":"Mannino",
|
||||
@@ -180,7 +180,7 @@
|
||||
"05a671c66aefea124cc08b76ea6d30bb","updated_at":"2014-03-09T13:58:28Z","user_id":6},{"admin":null,"created_at":
|
||||
"2014-03-10T00:13:12Z","email":"test2@test.com","first_name":"test","id":7,"last_name":"test","password":
|
||||
"91482305bacc71bd52612cce07135b77","updated_at":"2014-03-10T00:13:12Z","user_id":7}]
|
||||
</pre>
|
||||
</pre>
|
||||
<p><b> Broken Regular Expression SOLUTION:</b></p>
|
||||
<p class="desc">
|
||||
There are many things wrong with how we are going about doing this but, for a simple fix, you can anchor the regular expression to reject/ignore newline characters.
|
||||
@@ -196,7 +196,7 @@
|
||||
(id && hash) ? true : false
|
||||
check_hash(id, hash) ? true : false
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -213,7 +213,7 @@
|
||||
An API token? Interested to see what calls I can make! What are the closing tags for Ruby again?
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@
|
||||
decoded = Base64.strict_decode64("#{val}")
|
||||
aes.update("#{decoded}") + aes.final
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
We have placed this code under the lib directory so that we have a re-usable encryption routine. This code is used to generate a user's <b><i>auth_token</b></i> cookie responsible for authorization and access. However, we've also used this same code when encrypting a user's bank account number. This means, a user can enter in any value they would like and will receive it's encrypted equivalent back from the application. Essentially, a user has the ability to generate the auth_token cookie for any user ID and authorize as that user.<br/><br/>
|
||||
Within the app/models/pay.rb file we have a before hook that will save a user's bank account number as an encrypted value:
|
||||
@@ -62,14 +62,14 @@
|
||||
<pre class="ruby">
|
||||
# callbacks
|
||||
before_save <span style="background-color:yellow">:encrypt_bank_account_num</span>
|
||||
|
||||
|
||||
def encrypt_bank_account_num
|
||||
self.bank_account_num = <span style="background-color:yellow">Encryption.encrypt_sensitive_value(self.bank_account_num)</span>
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Additionally, we render that encrypted value (purposefully) when the <b><i>show</i></b> action is created within the app/controllers/pay_controller.rb file:
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
def show
|
||||
respond_to do |format|
|
||||
@@ -79,16 +79,16 @@
|
||||
</pre>
|
||||
<p class="desc">
|
||||
Lastly, we re-use this same routine within the following code is used to create a user's <b><i>auth_token</b></i> cookie upon sign-up or creation (app/models/user.rb):
|
||||
</p>
|
||||
</p>
|
||||
<pre class="ruby">
|
||||
before_create { generate_token(:auth_token) }
|
||||
|
||||
|
||||
def generate_token(column)
|
||||
begin
|
||||
self[column] = <span style="background-color:yellow">Encryption.encrypt_sensitive_value(self.user_id)</span>
|
||||
end while User.exists?(column => self[column])
|
||||
end
|
||||
</pre>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -126,7 +126,7 @@
|
||||
My "Remember Me" cookie looks familiar, almost like one of those values you get when you enter your bank account number.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user