ColdFusion Application Security: The Next Step Jason Dean www.12robots.com Boston ColdFusion User Group September 16th, 2009
Download
Report
Transcript ColdFusion Application Security: The Next Step Jason Dean www.12robots.com Boston ColdFusion User Group September 16th, 2009
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
deletePage.cfm?pageid=#pageID#
Request Forgeries
Brrrriiiiiiinnnng
The website
Brrriiiinnnng
is down!!!
Brrrrrriiinnng
Kay
???
Heh.
Bob
Request Forgeries
So What Happened?
Request Forgeries
muwhahaha
<img src=”http://easilypwnd.com/deletePage.cfm?pageID=1” />
<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>
Kay
Bob
So what can we do about it?
<form action="deletePage.cfm" method="post">
<input type="hidden" name="pageid" value="1" />
<input type="submit" name="btnSubmit" value="Delete" />
</form>
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
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?
Action Page/Method
<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 --->
Request Forgeries
Question?
Password Security
Achieving a Secure Password
AlphaNumeric
Uppercase
Lowercase
Password1!
Special
Characters
Minimum Length
Not a Date
Not Username
Change Regularly
•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
7FA8A6E9FDE2F4E1DFE6FB029AF47C9633D4B7A616A42C3B2889C5226A
20238D
ECB12086B0B57E445BED6C67EF6EB6C4F5A23360264646F9EF76E3E6679
87142
440CA7EEBEE13499DB9C01537442579C7E3B63C5F76F1B0A16DE18DDA7
E7704E
SHA-512 Result
27166A235CD42FB7E5A45CB89F542760373DCDC779E1697DB28301371890
4201D4D05537E63FD3815B596511C8704C50791C7BA3C504CAB516E62
2BDC6EC09C9
8C205EA4105BE9D89D44E84B4D00BCD52A84476180FEE63D99300AB4B2
3F2C30B77D6F7FD64D1B902F9BE85373D7394103EA58EDA174AD4589
2FDE0A56F0EF04
791FEDFCA713F52A42DDA68704213F5D8F5BC85953F385DF8D7835A7B32
FBFD16047C213883D46DC0834DB7A6F2549EAF7AB8CF264C8A6C9082
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?
SessionID=1
SessionID=2
GET index.cfm HTTP/1.1 Cookie: SessionID=1
SessionID=3
SessionID=3
GET index.cfm HTTP/1.1
Cookie: SessionID=2
GET index.cfm HTTP/1.1 Cookie: SessionID=1
sessionid=0a30b0926a39d5d7327237217c552e387712
HTTP/1.1 200 OK index.cfm Set-Cookie: SessionID=1
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 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
•<input type="hidden" name="cfid" value="#session.cfid#">
•<input type="hidden" name="cftoken" value="#session.cftoken#">
•
In a Cookie
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
• [email protected]
• http://www.12robots.com