370 likes | 384 Views
October 1st, 2008 Jason Dean http://www.12robots.com. Twin Cities ColdFusion User Group Intro to Application Security Part 2. Who am I?. Web Application Developer with the Minnesota Department of Health (MDH) Chairperson and User Group Manager of the MDH ColdFusion User Group
E N D
October 1st, 2008 Jason Dean http://www.12robots.com Twin Cities ColdFusion User GroupIntro to Application SecurityPart 2
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
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 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
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.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 • <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: <imgsrc="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: <imgsrc="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: <formname="rfForm"action="deletePage.cfm"method="post"> <inputtype="hidden"name="pageid"value="1"/> </form> <scripttype="text/javascript"> rfForm.post(); </script>
So what can we do about it? • So let's say we have a form that looks like this: <formaction="deletePage.cfm"method="post"> <inputtype="hidden"name="pageid"value="#queryPages.pageid#"/> <inputtype="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 /> <formaction="deletePage.cfm"method="post"> <inputtype="hidden"name="pageid"value="#queryPages.pageid#"/> <inputtype="submit"name="btnSubmit"value="Delete Page #queryPages.pageid#"/> <inputtype="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: <cfifStructKeyExists(form, "key") AND form.key = Hash(session.formkey.delPageForm, "SHA-256")> <cfsetstructDelete(session.formkey, "delPageForm") /> <cfelse> <cflocationurl="/"/> </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 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: <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) 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: <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 27166A235CD42FB7E5A45CB89F542760373DCDC779E1697DB283013718904201D4D05537E63FD3815B596511C8704C50791C7BA3C504CAB516E622BDC6EC09C9 0452F87278847018D8E6CC77F4201315AED6928A7A4075B2400D271CE8E89B1F848BFDC3B9F3A7EB2D74862EB984882C8F8D1F955E9E96F801B1419F88811A0B 4FF17CC3794CAB06B880FDA5507692ADBE5BA74EDFE570611F944F43DFFE4F0A0BED2F9CBC37FE1659336038ECABE47423FFA8FC8403459D7406E13A80173259
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 ExampleOutput <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 jason@12robots.com http://www.12robots.com AIM: IZB Jason Google Chat: deanj200