410 likes | 548 Views
ColdFusion Application Security: The Next Step. Jason Dean www.12robots.com. Boston ColdFusion User Group September 16 th , 2009. Who I am. Web Application Developer with the Minnesota Department of Health (MDH) User Group Manager of the MDH CFUG
E N D
ColdFusion Application Security: The Next Step Jason Dean www.12robots.com Boston ColdFusion User Group September 16th, 2009
Who I am • Web Application Developer with the Minnesota Department of Health (MDH) • User Group Manager of the MDH CFUG • Web Development Blogger (http://www.12robots.com) • Veteran of the U.S. Coast Guard
The Next Steps • Request Forgeries • Password Security • Cookie Misuse/Exploits • Session Management
Request Forgeries Hackers writing checks for your users to cash
That was confusing EXAMPLE deletePage.cfm?pageid=#pageID#
Request Forgeries Brrrriiiiiiinnnng Brrriiiinnnng Brrrrrriiinnng ??? The website is down!!! Heh. Bob Kay
Request Forgeries So What Happened?
Request Forgeries muwhahaha <img src=”http://easilypwnd.com/deletePage.cfm?pageID=1” /> <formname="hackerForm"action="http://easilypwnd.com/deletePage.cfm"method="POST"> <inputtype="hidden"name="pageID"value="1"/> </form> <scripttype="text/javascript"> hackerForm.post(); </script> Bob Kay
So what can we do about it? • The receiving action page/method probably: • Receives the request • Checks to make sure the user is authorized • Confirms that the ID is valid • Performs the action <formaction="deletePage.cfm"method="post"> <inputtype="hidden"name="pageid"value="1"/> <inputtype="submit"name="btnSubmit"value="Delete"/> </form>
How do we fix it? <cfset session.deleteForm.CSRFToken = createUUID() /> <cfset session.deleteForm.tokenExpires = DateAdd('m', 10, Now()) /> <formaction="deletePage.cfm"method="post"> <inputtype="hidden"name="pageid"value="1"/> <input type="hidden" name="key" value="#session.deleteForm.CSRFToken#" /> <inputtype="submit"name="btnSubmit"value="Delete Page 1"/> </form>
How do we fix it? • Action Page/Method <cfifNOTStructKeyExists(form, "CSRFToken") OR NOTStructkeyExists(session.deleteForm, "CSRFToken") OR NOTStructkeyExists(session.deleteForm, "tokenExpires") OR NOTIsDate(session.deleteForm.tokenExpires) OR NOT session.deleteForm.CSRFToken EQ form.CSRFToken OR NOTDateDiff("s",Now(),session.deleteForm.tokenExpires) GT0> <cflogfile="Security"type="warning"text="Possible CSRF Attack"> <cfthrowmessage="Access denied"> <cfelse> <cfsetStructDelete(session.deleteForm, "token")> <cfsetStructDelete(session.deleteForm, "tokenExpires")> </cfif> <!--- Continue Processing Form --->
Request Forgeries • Question?
Achieving a Secure Password AlphaNumeric Uppercase Lowercase Password1! Special Characters Minimum Length Not Username Not a Date Change Regularly
Password Hashing What is it? Why Do it?
Hashing Example • <cfset val1 = "Jason"/> • <cfset val2 = "CFML"/> • <cfset val3 = "jQuery is Awesome!!!"/> • <cfset hash1 = Hash(val1,"MD5") /> • <cfset hash2 = Hash(val2,"MD5") /> • <cfset hash3 = Hash(val3,"MD5") /> • <cfoutput>#hash1#</cfoutput><br/> • <cfoutput>#hash2#</cfoutput><br/> • <cfoutput>#hash3#</cfoutput><br/>
Hashing Example • 472D46CB829018F9DBD65FB8479A49BB • C2AF2111FF9C02C4EEE016CBCDF0D033 • 21AB8E7B12BA1793AB5156022492A5CD
Stronger Hashing Example • 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") /> <cfset hash1 = Hash(val1,"SHA-512") /> <cfset hash2 = Hash(val2,"SHA-512") /> <cfset hash3 = Hash(val3,"SHA-512") />
MD5 Result • 472D46CB829018F9DBD65FB8479A49BB • CBD672C9AAF85A22968C7BCF9FF90EED • 10F1C46CAF873486E530570E7A298BBB
SHA-256 Result • 7FA8A6E9FDE2F4E1DFE6FB029AF47C9633D4B7A616A42C3B2889C5226A20238D • ECB12086B0B57E445BED6C67EF6EB6C4F5A23360264646F9EF76E3E667987142 • 440CA7EEBEE13499DB9C01537442579C7E3B63C5F76F1B0A16DE18DDA7E7704E
SHA-512 Result • 27166A235CD42FB7E5A45CB89F542760373DCDC779E1697DB283013718904201D4D05537E63FD3815B596511C8704C50791C7BA3C504CAB516E622BDC6EC09C9 • 8C205EA4105BE9D89D44E84B4D00BCD52A84476180FEE63D99300AB4B23F2C30B77D6F7FD64D1B902F9BE85373D7394103EA58EDA174AD45892FDE0A56F0EF04 • 791FEDFCA713F52A42DDA68704213F5D8F5BC85953F385DF8D7835A7B32FBFD16047C213883D46DC0834DB7A6F2549EAF7AB8CF264C8A6C9082A2D0B5A420FFD
Hashing • Question?
Password Salting Because users make stupid passwords
Salting Example • <cfset val1 = "Password1"/> • <cfset val2 = "Password1"/> • <cfset hash1 = Hash(val1, "MD5") /> • <cfset hash2 = Hash(val2, "MD5") /> • <cfset hash1Salted = Hash(val1 & "salt1", "MD5") /> • <cfset hash2Salted = Hash(val2 & "salt2", "MD5") /> • <cfoutput>Value 1 Hashed: #hash1#</cfoutput><br/> • <cfoutput>Value 2 Hashed: #hash2#</cfoutput><br/> • <br/> • <cfoutput>Value 1 Salted and Hashed: #hash1Salted#</cfoutput><br/> • <cfoutput>Value 2 Salted and Hashed: #hash2Salted#</cfoutput><br/>
Salting Example Output • Value 1 Hashed: 2AC9CB7DC02B3C0083EB70898E549B63 • Value 2 Hashed: 2AC9CB7DC02B3C0083EB70898E549B63 • Value 1 Salted and Hashed: BAD4613B67109FD512580E3E67511652 • Value 2 Salted and Hashed: 3BB315CF3BA97066614C79832C939098
Password Hashing and Salting • Question?
What is a session? SessionID=1 SessionID=2 GET index.cfm HTTP/1.1 Cookie: SessionID=3 Cookie: SessionID=1 SessionID=3 sessionid=0a30b0926a39d5d7327237217c552e387712 GET index.cfm HTTP/1.1 Cookie: SessionID=1 GET index.cfm HTTP/1.1 Cookie: SessionID=2 HTTP/1.1 200 OK index.cfm Set-Cookie: SessionID=1
Session Token Types ColdFusion JEE • CFID & CFTOKEN • Weak by default • Can be made strong • Persistent by default • Can be set Session-Only • Easier to manipulate token cookies • Cannot be invalidated • JSESSIONID • Strong by Default • Session-Only by default • Can be shared with JEE applications • Can be invalidated
Session Persistence • Sessions can be persisted in 3 ways • In the URL String • http://www.12robots.com/mypage.cfm?CFID=2&CFTOKEN=10666880 • In POST request • In a Cookie • <inputtype="hidden"name="cfid"value="#session.cfid#"> • <inputtype="hidden"name="cftoken"value="#session.cftoken#">
Manipulating CF Token Cookies In Application.cfc: <cfset this.name = "sessionManagementApp"> <cfset this.sessionManagement = true> <cfset this.sessionTimeout = CreateTimeSpan(0,0,20,0) /> <cfset this.setClientCookies = false/> <cffunctionname="onSessionStart"output="false"> <cfheadername="Set-Cookie" value="CFID=#session.CFID#;secure=true;HTTPOnly"/> <cfheadername="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;secure=true;HTTPOnly"/> </cffunction>
Manipulating JEE Token Cookies In Application.cfc: <cffunctionname="onSessionStart"output="false"> <!--- Expire the old Cookie ---> <cfcookiename="jsessionid"expires="now"/> <!--- Get the HTTP Response Object ---> <cfset response = getPageContext().getResponse() /> <!--- Set the specifics for the cookie ---> <cfset path = "/test"/> <cfset domain = "my.local"/> <cfset secure = ""/><!--- Use val of "Secure" or leave blank ---> <cfset HTTPOnly = ""/><!--- Use val of "HTTPOnly" or leave blank ---> <cfscript> header = "jsessionid" & "=" & session.sessionid & ";domain=" & domain & ";path=" & path & ";" & secure & ";" & HTTPOnly; response.addHeader("Set-Cookie", header); </cfscript> </cffunction>
Session Logout (ColdFusion) In UserService.cfc: <cffunctionname="logout"output="false"access="remote"> <cfheadername="Set-Cookie"value="CFID="/> <cfheadername="Set-Cookie"value="CFTOKEN="/> <cfsetStructDelete(session, "auth") /> <cfset session.invalid = true/> <cflocationurl="/"addtoken="false"> </cffunction> In Application.cfc: <cffunctionname="onRequestStart"output="false"> <cfifStructKeyExists(session, "invalid") AND session.invalid EQtrue> <cfheadername="Set-Cookie"value="CFID="/> <cfheadername="Set-Cookie"value="CFTOKEN="/> <cflocationurl="/"addtoken="false"> </cfif> </cffunction>
Session Logout (J2EE) In UserService.cfc: <cffunctionname="logout"output="false"access="remote"> <cfheadername="Set-Cookie"value="CFID="/> <cfheadername="Set-Cookie"value="CFTOKEN="/> <cfsetStructDelete(session, "auth") /> <cfset getPageConext().getSession().invalidate() /> <cflocationurl="/"addtoken="false"> </cffunction>
Session Management • Question?
Cookie Parameters • Name • Value • Expires • Path • Domain • Secure • HTTPOnly
Cookie Domain and Path • www.awesomebloggers.com • 12robots.awesomebloggers.com • domain=”.awesomebloggers.com” • hacker.awesomebloggers.com • domain=”.12robots.awesomebloggers.com” • www.awesomebloggers.com/12robots • Path=”/” • www.awesomeblogers.com/hacker • path=”/12robots”
Setting the HTTPOnly Flag <cfheadername="Set-Cookie"value="name=value;HttpOnly">
Questions? • Please ask your questions now • Comments? • Jason Dean • jason@12robots.com • http://www.12robots.com