coldfusion application security: the next step jason dean boston coldfusion user group september 16...
TRANSCRIPT
ColdFusion Application Security: The Next Step
Jason Deanwww.12robots.com
Boston ColdFusion User Group September 16th, 2009
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
Who I am
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
KayBob
Heh.
The website is down!!! ???
BrrrriiiiiiinnnngBrrriiiinnnngBrrrrrriiinnng
Request Forgeries
So What Happened?
Request Forgeries
KayBob
<img src=”http://easilypwnd.com/deletePage.cfm?pageID=1” />
muwhahaha
<form name="hackerForm" action="http://easilypwnd.com/deletePage.cfm" method="POST"> <input type="hidden" name="pageID" value="1" /></form>
<script type="text/javascript"> hackerForm.post();</script>
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
<form action="deletePage.cfm" method="post"><input type="hidden" name="pageid" value="1" /><input type="submit" name="btnSubmit" value="Delete" />
</form>
How do we fix it?
<cfset session.deleteForm.CSRFToken = createUUID() /><cfset session.deleteForm.tokenExpires = DateAdd('m', 10, Now()) />
<form action="deletePage.cfm" method="post"> <input type="hidden" name="pageid" value="1" /> <input type="hidden" name="key" value="#session.deleteForm.CSRFToken#" /> <input type="submit" name="btnSubmit" value="Delete Page 1" /></form>
How do we fix it?
<cfif NOT StructKeyExists(form, "CSRFToken") OR NOT StructkeyExists(session.deleteForm, "CSRFToken") OR NOT StructkeyExists(session.deleteForm, "tokenExpires") OR NOT IsDate(session.deleteForm.tokenExpires) OR NOT session.deleteForm.CSRFToken EQ form.CSRFToken OR NOT DateDiff("s",Now(),session.deleteForm.tokenExpires) GT 0> <cflog file="Security" type="warning" text="Possible CSRF Attack"> <cfthrow message="Access denied"><cfelse> <cfset StructDelete(session.deleteForm, "token")> <cfset StructDelete(session.deleteForm, "tokenExpires")></cfif>
<!--- Continue Processing Form --->
Action Page/Method
Request Forgeries
Question?
Password Security
Achieving a Secure Password
Not Username
Change Regularly
Minimum LengthSpecial Characters
AlphaNumeric LowercaseUppercase
Not a Date
Password1!
•Password Security Right for the Site
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
27166A235CD42FB7E5A45CB89F542760373DCDC779E1697DB283013718904201D4D05537E63FD3815B596511C8704C50791C7BA3C504CAB516E62
2BDC6EC09C9
8C205EA4105BE9D89D44E84B4D00BCD52A84476180FEE63D99300AB4B23F2C30B77D6F7FD64D1B902F9BE85373D7394103EA58EDA174AD45892F
DE0A56F0EF04
791FEDFCA713F52A42DDA68704213F5D8F5BC85953F385DF8D7835A7B32FBFD16047C213883D46DC0834DB7A6F2549EAF7AB8CF264C8A6C9082
A2D0B5A420FFD
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?
Session Management
What is a session?
HTTP/1.1 200 OK index.cfm
GET index.cfm HTTP/1.1
GET index.cfm HTTP/1.1
GE
T in
de
x.cf
m H
TT
P/1
.1
SessionID=3
SessionID=1SessionID=2 Cookie: SessionID=3
Cookie: SessionID=1
Co
oki
e:
Se
ssio
nID
=2
Set-Cookie: SessionID=1
Cookie: SessionID=1
sessionid=0a30b0926a39d5d7327237217c552e387712
Session Token Types
ColdFusion
• 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
JEE
• JSESSIONID• Strong by Default• Session-Only by default• Can be shared with JEE
applications• Can be invalidated
Session PersistenceSessions 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
•<input type="hidden" name="cfid" value="#session.cfid#">•<input type="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 />
<cffunction name="onSessionStart" output="false"><cfheader name="Set-Cookie"
value="CFID=#session.CFID#;secure=true;HTTPOnly" /><cfheader name="Set-Cookie"
value="CFTOKEN=#session.CFTOKEN#;secure=true;HTTPOnly" /></cffunction>
Manipulating JEE Token Cookies
In Application.cfc:<cffunction name="onSessionStart" output="false">
<!--- Expire the old Cookie ---><cfcookie name="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:<cffunction name="logout" output="false" access="remote">
<cfheader name="Set-Cookie" value="CFID=" /><cfheader name="Set-Cookie" value="CFTOKEN=" />
<cfset StructDelete(session, "auth") /><cfset session.invalid = true />
<cflocation url="/" addtoken="false"></cffunction>
In Application.cfc:<cffunction name="onRequestStart" output="false">
<cfif StructKeyExists(session, "invalid") AND session.invalid EQ true><cfheader name="Set-Cookie" value="CFID=" /><cfheader name="Set-Cookie" value="CFTOKEN=" />
<cflocation url="/" addtoken="false"></cfif>
</cffunction>
Session Logout (J2EE)
In UserService.cfc:<cffunction name="logout" output="false" access="remote">
<cfheader name="Set-Cookie" value="CFID=" /><cfheader name="Set-Cookie" value="CFTOKEN=" />
<cfset StructDelete(session, "auth") /><cfset getPageConext().getSession().invalidate() />
<cflocation url="/" addtoken="false"></cffunction>
Session Management
Question?
Cookie Security
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
<cfheader name="Set-Cookie" value="name=value;HttpOnly">
Questions?
• Please ask your questions now
• Comments?
• Jason Dean
• http://www.12robots.com