ColdFusion Summit 2021 Notes: Tackling ColdFusion Security, Pete Freitag
We’re all impacted by security hacks.
Even the smartest devs will have security vulnerabilities in their code.
Sometimes as devs we try to chase the idea that we can have things that are perfect but there will always be bugs in code.
Not likely that your code will never have security issues but you can’t ignore it.
Probably a good time to take action on it if you’ve been ignoring it.
Security breaches have been skyrocketing.
CVEs tripled from 2015 to 2020.
Difficult to stay on top - constantly coming at you with fixes.
Difficult problem to tackle, humans are constantly failing.
Avoid being an easy target -
Make a goal for 2022: improve the security of my web apps.
Don’t go it alone -
Tools you can use:
Unit / integration tests
Support from colleagues
Management might want to improve it, but may not know what needs to be done.
If you go to management and say "I want to improve the application's security", they might have the assumption they were already secure.
Set the expectation that this is something that needs to be constantly improved.
10 places to start --
Delete Old Code --
“Home made version control”
Use REAL version control instead.
Old files may have old security holes in them.
The fewer files you have to maintain, the less time spent figuring out where the bugs are.
Version control has the file if you made a mistake and deleted something you actually need.
There are lots of fads in Software Development, version control is NOT one of them.
Ways to identify obsolete code:
find /wwwroot/ -atime +365
...finds code that hasn’t been accessed in a year.
Delegate Risky Areas --
- Delegate to a payment gateway
- Braintree, Stripe, etc, may lessen PCI requirements
If you can offload that risk, that improves your security, removes security burdens.
Leverage a SSO solution.
Enterprise: Active Directory, LDAP, etc.
Social: Google, Facebook, Twiter, etc.
Other areas: Encryption, Secrets, Key Management.
DELETE your auth code!
Delegate that to a provider.
Can do that with a protocol called SAML.
OAuth is also an option
No longer have to store passwords!
Users will notice and like it -- they don't need a separate password just for your app
Both a security and a UX improvement
How does SAML work?
User visits the app.
Your app redirects to the "Identity Provider".
From there, the provider has the login page for the user (with 2FA).
Once the identity provider says "this is a valid login", redirects back to your app wiht a secret key/signature that you can verify to ensure it's authentic, marks the user as "logged in" and identity of the user.
ColdFusion 2021 SAML Integration
Java libs - java-saml or opensaml
Can roll your own but that kind of defeats the purpose.
Secrets / Key Mgmt
Avoid using source code for storing secrets.
Use a key/secret mgmt API.
Various cloud based ons - AWS, KMS, Secrets Mgr, EC2 Parameter Store.
Azure: Key Vault
On-site option: Hashicorp Vault
Good idea to delegate sensitive operations to these outfits.
“assume breach” driven.
Changes how you go about setting things up.
Follow principle of least privilege.
User should only have permissions to do the task they are allowed to do and nothing more.
“need to know basis” kind of thing.
Helps minimize impact if you did have a breach.
Lock Down ColdFusion
What user is the JVM running as?
Is your CFML server is running as System or root?
Assume breach - limit impact if it’s breached.
What permission does the user have?
If CFML server, user only has readonly access to webroot and CFML server install dir then less harm can be done.
Does CFML server need full write access to webroot?
Lock Down Database
Limit what the datasoruce can do.
Is it a readonly database or table, then it only needs SELECT perms.
Injection Attacks --
<p>Hi #encodeForHTML( url.name )#</p>
Similar to XSS
If URL.name is an <img> tag, it’s going to perform that GET request to try and fetch that image.
Applies to cfdocument and cfhtmltopdf
Be careful with the variables you’re outputting in a PDF
Scope Injection —
Takes advantage of scope cascading
Suppose you have a session.userid
Now assume the var is not yet defined in the session scope (user not yet logged in)
If I request /admin/page.cfm?session.userid=1
CF will check the session scope first, but if not defined it will check all the other scopes - url, form, etc.
Here url.sesion.user.id is defined and would be used
Make sure session vars are ALWAYS defined and initialized to a value
Set the session.userid
So that it can’t be taken advantage of in this way
isDefined() is not great, allows for scope injection
structKeyExists() and session.keyExists() are better
Application.cfc - this.searchImplicitScopes = false
Will prevent the scope cascading, but might also break your app if you’re not careful about how you scoped your vars (will have to test your entire app when you make this change)
Other Injection Attacks —
XML Entity Injection
Command Injection (cfexecute, etc)
See OWASP for details — good resource, owasp.org — their cheat sheet is a great resource for a list of attacks
XSS - Cross Site Scripting
Hi #url.name# — vulnerable
Hi #encodeForHTML( url.name )# — safe
Use encoder functions when possible
,for CSS, etc
<cfoutput encodefor=‘html”>#url.hame#</cfoutput> — safe just like the function
When encodeFor functions can’t be used, use isSafeHTML or getSafeHTML (not perfect, but a good stop-gap when the functions aren’t avaialble)
Add Content-Security-Policy headers
- gets turned on when the browser sends back this header
- turns on a sandbox for what’s allowed to execute on the page
- ex: only allow image to be loaded from “self” — this domain that the page is on
— if someone tries to load an image from another domain, the browser will block it
— helps mitigate XSS (on browsers that support it)
not a perfect solution, but a pretty good one
XSS can be pesky and time consuming to deal with
Authentication / Authorization --
— don't want to have plain text passwords stored in the database
Credential stuffing attacks, rate limiting
Password reset flows
Most common problem: missing authentication, the developer just forgot to do the authorization check somewhere in the app.
Is THIS user authorized to view THIS data?
Hard to detect these things with automated tools
Can write integration tests to check this
OWASP Authentication Cheat Sheet and Authorization Cheat Sheet
both good resources
Remote Code Execution --
anything that gets passed in to this, can be executed as CFML
Evaluate( url.day )
Search code for Evaluate()
In most case you don’t need it
Use brackets instead
IIF() - 2nd and 3rd args are evaluated dynamically!
Same problem as Evaluate()
Use ternary or Elvis operators instead
SQL Injection --
Sites still get exploited this way even today
SELECT * FROM news
WHERE id = #url.id#
Finding SQL Injection -
search codebase for cfquery, queryexecute, ORM functions, etc.
Path Traversal -
Avoid variables in paths
if you really need to use a var strip out everything that's not a-z0-9
Use thecf11+ Application.cfc setting this.compileExtForInclude
Set this to something like ‘.cfm only’
File Uploads, Core Rules --
Never Trust the MIME type
Always validate the file extention
Specify file path fully
Un-patched known vulnerabilities --
Make sure you apply your patches
Different vulnerabilities can occur because you didn’t apply the patch
Nearly 60% of breaches are due to Un-patched vulnerabilities