Presentation on theme: "Twin Cities ColdFusion User Group Intro to Application Security Part 2 October 1st, 2008 Jason Dean"— Presentation transcript:
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 On- Site) 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.comhttp://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-of- the-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 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: 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 tag went looking for the src resource and made the request: 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 attack, but not this one: rfForm.post();
So what can we do about it? So let's say we have a form that looks like this: 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? 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:
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 #hash1# #hash2# #hash3# Will Produce: 472D46CB829018F9DBD65FB8479A49BB CBD672C9AAF85A22968C7BCF9FF90EED 10F1C46CAF873486E530570E7A298BBB Notice they are all the same number of characters. Hashes are Fixed- Length 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: 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) FIPS- 180-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: Now let's add: AND
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 Value 1 Hashed:#hash1# Value 2 Hashed:#hash2# Value 1 Salted and Hashed:#hash1Salted# Value 2 Salted and Hashed:#hash2Salted#
Password Salting Example Output Value 1 Hashed:#hash1# Value 2 Hashed:#hash2# Value 1 Salted and Hashed:#hash1Salted# Value 2 Salted and Hashed:#hash2Salted# 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 firstname.lastname@example.org http://www.12robots.com AIM: IZB Jason Google Chat: deanj200