CF Summit notes - Application Security Part 2, Jason Dean

October 29, 2013

Application Security Part 2 - Jason Dean

SSL is old school we use TLS now for secure browser stuff
cfScriptProtect is a waste of time, don't use it
ALWAYS use Hash() when working with passwords

xss - the most prevailing vulnerability in web apps today
logging is an essential tool for not just debugging but also for security

there are different ways to secure your app depending on your needs, business req's, clients, etc.

cfmx_compat - sucks, it's default, and it's BARELY crypto. don't use it!
if you are not specifying an algo in crypt, you're doing it wrong
have other choices
cfmx_compat
blowfish
des
tripeDES
AES
...
ONLY use Blowfish, TripleDES and AES
only acceptable choices for PCI compliance

modes of operation--
electronic code book (ECB)
-- avoid this
cipher block chaining (CBC)
-- each encrypted block depends on the encrypted block before it
-- makes breaking it REALLY hard

Simple AES crypto

SPECIFY the algorithm
if you don't, you get cfmx_compat by default...bad bad bad

decrptedText = decrypt( chipertext, key, "AES", "hex" )

simple. but not good enough
AES is fast, secure, strong, but by default its not quite ready
this does ECB
we really want to use CBC if possible

by default JEE limits the strength of crypto (due to import laws in other countries)
max of 128bit

using PKI in CF
check Jason's blog for any info on this.

(separate 1 hour press Jason did just on crypto, check UGTV)

Insecure Direct Object reference
an object is a database record, file, folder, or other assets
directly accessing them can be dangerous
relatively easy to fix
1 way is to use an "object reference map"
can also encrypt form and url variables
and use access control and validation -- make sure the CC# that was submitted actually belongs to the guy that's logged in

Indirect Reference Maps
in session scope, put the primary key here, but a DIFFERENT value in to "map" to the CC# (for example)
use that different value for the HTML
them just do

structFindValue(map, url.cc_id)[1].key

on the receiving side:

session.map[ url.cc_id ]

wrap it in try/catch so it doesn't die when hackers try to manipulate the URL (thinking it's a primary key)

session security --
most of the time we don't have to worry about session mgmt. it just works

broken authentication and session mgmt
things we need to do to strengthen session mgmt
in older versions of CF this was not as secure, but better now
session mgmt in CF by default cannot do everything you want
might need to roll your own solution
(specially if you want SOME pages to be secured by SSL and some not)

session tokens --
CF9 improved the randomness of cftokens
UUID tokens are FINALLY the default in CF10
(in 9 and below it was terribly not random, and was an 8 digit number...easy to hack)
if you're still using those easy to guess older tokens, log in remotely and switch NOW.

"use UUID for cftoken"

CF9.01 added support for "httponly" session cookies
JEE tokens are also a good choice
can go into cf admin and click "use j2ee session variables"
-- have the servlet container (tomcat, etc) generates the tokens FOR you, instead of having CF doing it
-- some tradeoffs with this

best practices
-- do NOT pass tokens on the URL strong
addtoken=false on ALL your cflocation calls
(the DEFAULT is "true"!)

use 100% SSL/TLS for your sessions
EVERY page
if you can't do that, then you have to roll your own solutions and essential have to have TWO token solutions
need to ensure the SSL token is NEVER sent over a NON TLS connection. because then it becomes exposed and someone can hijack the user

TLS to NON-TLS switching is tough
easier/more secure to just have 100% TLS

use appropriate session timeout length
defacto standard is TWENTY minutes
unless you have sensitive data, drop it down to 5 minutes

when a user logs in, create a NEW session token
don't keep using the same one
especially if they're going form a non TLS connection to a TLS connection
because that token from before they logged in could have been compromised and used for hijacking
after they log in, invalidate that session and create a brand new one
CF10 has a function for this -- sessionrotate() (but this doesn't work with J2EE, but with that you can call session.invalidate() and get the same result)

use SECURE and HTTPONLY session cookies
always check "httponly" in cf admin
don't EVER want your session cookies available via javascript EVER

look into Cookie Domains and Cookie Paths
especially if you're serving multiple sites
www.site.com
admin.site.com
-- different sites but the SAME domain

Request forgery

in an email / joke forward:

hey click this!
<img src="http://site.com/admin/deletePage.cfm?pageid=1">

because it's in an IMG tag, it will make an HTTP request to that. and boom, the site goes down
can also do it just as easily via a page submit/ form post

new to cf10
CSRFGenerateToken()
CSRFVerifyToken()

can use to ensure that a form submit came from where it SHOULD come from.
helps pre vest the request forgery example we just saw

on CF9 or below, process is more convoluted but not impossible
generate the token yourself (createuuid(), etc)
pass that in them form a variable
and save it to user's session
then create your own check to make sure that uuid in the form, url, and session scope match
if not, return false.

XSS

understand data and code contexts
data context is for display
the space between 2 DIV tags is for display
no code in there should be -executed-

code context - for things that should be EXECUTED
code between 2 script tags
XSS involves breaking out of data context and into code context
or involves manipulating an existing code context to behave differently

each context must be handled differently
can't just use HTMLFormat() everywhere


...gives ANYone ability to execute javascript in the users browser


...user clicks it, and javscript runs in their browser
will cause that script code to RUN on the user's browser

if hacker can run that alert, they can run ANY javascript code on the user's browser
redirect to a new site
key captures
steal session cookies, etc.

there is no good reason to send cookies via javascirpt
(ajax requests send the cookie automatically, you don't have to do anything to make those work)
set httponly for cookies. ajax still works just fine

OWASP ESAPI Project
FREE open source web app security control library. essential a framework for writing your own security framework
it's a java project, so we can use it in CF
(there is an esapi for cf)

if it is UNtrusted content, then display it like this;

a href=""
different than display context, needs to be treated differently
a href="#url.link#"
to fix
encodeforHTMLAttribute()
...slightly differently than encoding things for display.

blacklist security does NOT work, don't rely on it

escape your output

JavaScript events (on click, onmouseover, etc0 are NOT in the HTML context, they're in the JavaScript context

JS context
1 inside script blocks
2. inside, say, onmouseover tag attributes

encodeForJavaScript( ... );

ALSO need to escape in the CSS context

encodeForCSS()

URL context
don't wrap the entire URL in encodeForURL()
wrap each parameter!

http://site.com/foo.cfm?param1=#encodeForURL(form.id)#...

other contexts
however you must instantiate esapi manually for those