MDH ColdFusion User Group Intro to Application Security

Download Report

Transcript MDH ColdFusion User Group Intro to Application Security

Twin Cities ColdFusion User Group
Intro to Application Security
Part 2
October 1st, 2008
Jason Dean
http://www.12robots.com
Who am I?



Web Application Developer with the Minnesota Department
of Health (MDH)
Chairperson and User Group Manager of the MDH
ColdFusion User Group
ColdFusion Blogger (Like who isn't?)



http://www.12robots.com
Veteran of the U.S. Coast Guard
Volunteer Web Developer with the Minnesota Valley
Humane Society
What are the threats/attacks?
• The basics
–
–
–
–
–
–
SQL Injection
Cross-Site Scripting XSS
Cookie Misuse/Exploits
Access Control Attacks
Input Validation Exploits
File Uploads
• The less obvious
–
–
–
–
Ignorance
Assumptions
Laziness
Internal threats
• The Advanced
– Session Management Attacks
– Authorization/Authentication
– Request Forgeries (on-site and
cross-site)
–
–
–
–
Exception Management
Cryptography
Parameter Manipulation
Auditing and Logging
• The Beyond our Control
– Web Server Exploits
– Application Server Exploits
– Server configuration problems
What are we going to talk about?

Request Forgeries

Password Security
What is a Request Forgery?


A request forgery, also sometimes called a Cross-Site (or OnSite) Request Forgery(XSRF), is an attack that is perpetrated
against the user of a site who has authenticated access to that
site
The user is unwittingly tricked into performing actions on a site
through hidden code displayed to them and, therefore,
executed in their browser
That was confusing as hell...

How about an Example?

Our Hypothetical website http://www.easilypwnd.com

Has an administrator only section for maintaining users



Our site has a deletePage.cfm action page that accepts a single
parameter, pageID
Our deletePage.cfm has been secured through various,
effective means to make sure only our administrators can
access it.
All is good, right?
Or is it?


One morning, Bob (one of our administrators) gets an email
from Kay in accounting. It has a link to a bad joke on a Joke-ofthe-day sites
Here is the joke:



A sandwich walks into a bar and yells “Barkeep! Get me a
beer!”. The bartender looks at him and says, “I'm sorry, we
don't serve food here”.
Bob finishes the joke, chuckles politely and deletes the email
About 5 minutes later, the phone starts ringing. The company
website is down
What happened?

The email Bob received wasn't from Kay in accounting

<Insert maniacal laughter>

It was from a Hacker who spoofed Kay's email address

The link the hacker sent, did go to a Joke-of-the-Day pages, but
the hacker left a comment for the joke and in his comment he
placed the line:
<img src="http://www.easilypwnd.com/deletePage.cfm?pageid=1">

So what do you think happened when Bob viewed that page with
that comment on it?
What happened?

So when Bob view that pagem the <img /> tag went looking for
the src resource and made the request:
<img src="http://www.easilypwnd.com/deletePage.cfm?pageid=1">


And if Bob was actually logged into the site, then it was a
legitimate request coming from a legitimate user and so it was
executed
Oops
So what can be accomplished with an Request
Forgery Attack?

Delete or Edit pages

Delete or Edit Users

Perform Administrative Functions

Send Emails

Transfer funds

Make purchases

Anything that an authenticated used would normally be able to do
So what can we do about it?


One thing we can do is to use POST requests instead of GET requests.
Using POST will stop many, but not all Request Forgeries, It would stop
the <img /> attack, but not this one:
<form name="rfForm" action="deletePage.cfm" method="post">
<input type="hidden" name="pageid" value="1" />
</form>
<script type="text/javascript">
rfForm.post();
</script>
So what can we do about it?

So let's say we have a form that looks like this:
<form action="deletePage.cfm" method="post">
<input type="hidden" name="pageid" value="#queryPages.pageid#" />
<input type="submit" name="btnSubmit" value="Delete Page
#queryPages.pageid#" />
</form>


Assume that it has other appropriate security to ensure only
administrators have access
This is vulnerable to the forgery attack we just looked at
How do we fix it?
<cfset key = CreateUUID() />
<cfset session.formkey.delPageForm = key />
<form action="deletePage.cfm" method="post">
<input type="hidden" name="pageid" value="#queryPages.pageid#" />
<input type="submit" name="btnSubmit" value="Delete Page
#queryPages.pageid#" />
<input type="hidden" name="key" value="#Hash(key, "SHA-256")#" />
</form>

So by adding a hidden field with a new Hashed UUID key for every
request and then adding that Hash to the users session we can check
the result in the action page/method to confirm that it came from the
right place
How do we fix it?

Our Action Page/Method might look like this:
<cfif StructKeyExists(form, "key") AND form.key =
Hash(session.formkey.delPageForm, "SHA-256")>
<cfset structDelete(session.formkey, "delPageForm") />
<cfelse>
<cflocation url="/" />
</cfif>
<!--- Finish form processing here because it will only make it this far if the
session Hash matches the one posted --->
Password Security

How do we get a secure password?

Does every site need a “super” secure password?

Password Best Practices

Password Salting and Hashing

Password Strength Function

“Forgot My Password” Best Practices
Achieving a Secure Password






Password should allow and required both alphabetical and numeric
characters
Passwords should allow and require both uppercase and lowercase
letters
Passwords should allow and require special characters
Passwords should probably be at least 7 or 8 characters long. If you
need to have them with fewer characters, you should have a REALLY
good reason for it.
Password should be changed every [Insert period of time here].
Depending on the security level of your system this might be every
month, quarter, or six months. Weekly is probably overkill, except for
the most secure of systems and annually is probably too lax.
Passwords should never be, or even contain, the username.

Have the password security scheme fit
the website

Does every site need a “super” secure password?

Probably not

It is a judgment call, get the input of the people to whom data belongs


There is no reason not to allow a strong password, but perhaps not
every site needs to enforce it
At a minimum, set a decent minimum length and require some alphas
and some numerics
Best Practices

Don't set a minimum length above 8 character

Where possible, use SSL

Load the login form using SSL (although it only needs to POST to SSL)

Don't send Login credentials on th URL string (except for Web
Services, and then, only over SSL)

Never store passwords in clear text

Create an audit log of login attempts

If you lock a user out after a certain number of login attempts, do not
use a cookie or tie it to the user session, do it in the database
Password Hashing and Salting

What is Hashing?

Why do we want to Hash our passwords?

What is Salting and why do we want to do it?

Example Code
What is Hashing?

From Wikipedia: "... a Cryptographic Hash Function is a transformation
that takes an input and returns a fixed-size string, which is called the
hash value.

A hash is a One-Way Transformation

A strong enough hash is virtually impossible to reverse

A strong enough hash will have very few collisions
Hashing Example
<cfset val1 = "Jason" />
<cfset val2 = "ColdFusion" />
<cfset val3 = "SR-71 Blackbird" />
<cfset hash1 = Hash(val1,"MD5") />
<cfset hash2 = Hash(val2,"MD5") />
<cfset hash3 = Hash(val3,"MD5") />
<cfoutput>
#hash1#<br />
#hash2#<br />
#hash3#<br />
</cfoutput>
Hashing Example
<cfoutput>
#hash1#<br />
#hash2#<br />
#hash3#<br />
</cfoutput>
Will Produce:
472D46CB829018F9DBD65FB8479A49BB
CBD672C9AAF85A22968C7BCF9FF90EED
10F1C46CAF873486E530570E7A298BBB

Notice they are all the same number of characters. Hashes are FixedLength strings
Stronger Hashing Example





So an MD5 Hash is pretty strong, but it is not strong enough
MD5 is fine for examples, but in the real world, MD5 is weak
So what are the other options?
In our example we did this: <cfset hash1 = Hash(val1,"MD5") />
Well we can replace MD5 with a number of other hashing algorithms that
produce different fixed-lengths

MD5: (Default) Generates a 32-character, hexadecimal string, using the MD5
algorithm (The algorithm used in ColdFusion MX and prior releases).

SHA: Generates a 28-character string using the Secure Hash Standard SHA-1
algorithm specified by Nation Institute of Standards and Technology (NIST) FIPS180-2.

SHA-256: Generates a 44-character string using the SHA-256 algorithm specified
by FIPS-180-2.

SHA-384: Generates a 64-character string using the SHA-384 algorithm specified
by FIPS-180-2.

SHA-512: Generates an 88-character string using the SHA-1 algorithm specified by
FIPS-180-2.
Stronger Hashing Example


So let's compare the algorithms
In our previous example we had:
<cfset hash1 = Hash(val1,"MD5") />
<cfset hash2 = Hash(val2,"MD5") />
<cfset hash3 = Hash(val3,"MD5") />

Now let's add:
<cfset hash1 = Hash(val1,"SHA-256") />
<cfset hash2 = Hash(val2,"SHA-256") />
<cfset hash3 = Hash(val3,"SHA-256") />
AND
<cfset hash1 = Hash(val1,"SHA-512") />
<cfset hash2 = Hash(val2,"SHA-512") />
<cfset hash3 = Hash(val3,"SHA-512") />
Stronger Hashing Example
MD5 Result
472D46CB829018F9DBD65FB8479A49BB
CBD672C9AAF85A22968C7BCF9FF90EED
10F1C46CAF873486E530570E7A298BBB
Stronger Hashing Example
SHA-256 Result
7FA8A6E9FDE2F4E1DFE6FB029AF47C9633D4B7A616A42C3B2889C5226A20238D
0DBDC9C5C4E9B4B11FECFAC0247A0E0F0E810A7BD0AD3EEC36C2A30FF96CE3C4
E153B4C97FCFAC7016A276461E06504CB9F03B9A3ADF36072E1EC7F21308736B
Stronger Hashing Example
SHA-512 Result
27166A235CD42FB7E5A45CB89F542760373DCDC779E1697DB283013718904201D4D
05537E63FD3815B596511C8704C50791C7BA3C504CAB516E622BDC6EC09C9
0452F87278847018D8E6CC77F4201315AED6928A7A4075B2400D271CE8E89B1F848B
FDC3B9F3A7EB2D74862EB984882C8F8D1F955E9E96F801B1419F88811A0B
4FF17CC3794CAB06B880FDA5507692ADBE5BA74EDFE570611F944F43DFFE4F0A0B
ED2F9CBC37FE1659336038ECABE47423FFA8FC8403459D7406E13A80173259
Hashing

A specific string will ALWAYS result in the same hash value

Collisions occur when two values have the same Hash value

Strong hashing algorithms are going to have fewer collisions

The longer the hash value, the less likely you will have collisions.
Implementing Hashed Passwords




So if hashes aren't reversible, how can we tell if the user entered the
correct password?
When the user enters their password, while logging in, we hash it and
compare the result to the hash that we stored in the database.
Since a hash cannot be reversed, even if the DB becomes
compromised, the information cannot be used to obtain password, nor
can it be used to login using the hash instead of a password
We'll look at an example shortly
Password Salting

What is Salting?

Let's first talk about why we need salting

We need salting because people make stupid password

We also need passwords because hackers are smart




If our password database becomes compromised, and the passwords
are hashed, then the hacker will start looking like values
If the hacker finds two hashed values that are exactly the same then
that value is either a common dictionary word, a name, or a date
The brute force attack on that user can then commence
Salting ensures that no two hashes in our database ever have the
same value
Password Salting




So what is Salting then?
Salting is the process of adding a random string of characters to the
end of a user's password before hashing it.
Each password would get its own salt hence eliminating the problem of
two like passwords having the same hash value.
Let's look at examples
Password Salting Example
<cfset val1 = "Password1" />
<cfset val2 = "Password1" />
<cfset hash1 = Hash(val1, "MD5") />
<cfset hash2 = Hash(val2, "MD5") />
<cfset hash1Salted = Hash(val1 & CreateUUID(), "MD5") />
<cfset hash2Salted = Hash(val2 & CreateUUID(), "MD5") />
<cfoutput>
Value 1 Hashed:#hash1#<br />
Value 2 Hashed:#hash2#<br /><br />
Value 1 Salted and Hashed:#hash1Salted#<br />
Value 2 Salted and Hashed:#hash2Salted#<br />
</cfoutput>
Password Salting Example
Output
<cfoutput>
Value 1 Hashed:#hash1#<br />
Value 2 Hashed:#hash2#<br /><br />
Value 1 Salted and Hashed:#hash1Salted#<br />
Value 2 Salted and Hashed:#hash2Salted#<br />
</cfoutput>
Will result in this output:
Value 1 Hashed:2AC9CB7DC02B3C0083EB70898E549B63
Value 2 Hashed:2AC9CB7DC02B3C0083EB70898E549B63
Value 1 Salted and hashed:2DEB5ADAF0854BBBC24DC4797BA73027
Value 2 Salted and Hashed:3498DD83CA3F1945D0EE7BE16984999E
Password Salting Example
Value 1 Hashed:2AC9CB7DC02B3C0083EB70898E549B63
Value 2 Hashed:2AC9CB7DC02B3C0083EB70898E549B63
Value 1 Salted and hashed:2DEB5ADAF0854BBBC24DC4797BA73027
Value 2 Salted and Hashed:3498DD83CA3F1945D0EE7BE16984999E

Notice the hash without salting is identical between the two values

But, once you add a salt, the two values are very different

Of course, we need to store the salt that we use for each value so that
when we hash the user input, we can append the salt
Look at Code!
Let's look at some code examples
http://localhost:81/hashandsalt/index.cfm
http://localhost:81/hashandsalt/login.cfm
“Forgot My Password” Best Practices







Never have your “Forgot My Password” function e-mail the users password (If
you are hashing password you won't be able to anyway)
Either reset the users password and email them the new password or send the
user a temporary URL that can be used for them to reset the password
Force the user to change their password after they first log in after a reset
Keep a log of the last X hashes of the users password so they cannot reset
their password to something that have used previously (Within reason)
Make sure your Change Password functionality uses the same strength and
hashing functions as your initial password set up
Do not login a user from the “Forgot My Password” section. Always make them
go through their e-mail.
Tell story about bad “Forgot My Password” functionality
Questions?

Please ask your questions now

Or feel free to contact me
Jason Dean
[email protected]
http://www.12robots.com
AIM: IZB Jason
Google Chat: deanj200