Forcing HttpOnly cookies with JRun/ColdFusion - cookies

We need to ensure that all cookies on a CF7 site are set as HttpOnly.
We are using jsessionid to control our sessions, and JRun does not create this as HttpOnly.
Whilst it is possible to modify an existing cookie to add this setting, we need to have it set to HttpOnly from the start.
Any suggestions?
Related Question: Setting Secure flag for HTTPS cookies.

From: http://www.petefreitag.com/item/764.cfm
Running CF 8 or Lower and using Application.cfc
<cfcomponent>
<cfset this.sessionmanagement = true>
<cfset this.setclientcookies = false>
<cffunction name="onSessionStart">
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
</cffunction>
<cfcomponent>
Make sure you have setclientcookies = false specified.
If Using Application.cfm
If you are still using an Application.cfm file, you can use the following:
<cfapplication setclientcookies="false" sessionmanagement="true" name="test">
<cfif NOT IsDefined("cookie.cfid") OR NOT IsDefined("cookie.cftoken")>
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
</cfif>

First, a warm welcome to all PCI DSS refugees! Appscan, Webinspect, Hailstorm and NTOSpider fugitives are also invited. Take a seat right over here, I have cake for you:
While too late for Peter, it is in fact possible to have JRun generate HTTPOnly (and secure) cookies from the start as he asked. Look for the jrun-web.xml file. It will probably be in a directory like
C:\JRun4\servers\servername\cfusion-ear\cfusion-war\WEB-INF\.
You have to add the following to the cookie-config section:
<cookie-config>
<cookie-path>/;HttpOnly</cookie-path>
</cookie-config>
If your site is HTTPS, you should also enable the secure cookie option. But be careful, its server wide, not application specific. So it may not be suitable for your shared environment:
<cookie-config>
<cookie-secure>true</cookie-secure>
<cookie-path>/;HttpOnly</cookie-path>
</cookie-config>
If you are not stuck in MX7 or CF8, there is an official setting for this in CF9.01 Dcoldfusion.sessioncookie.httponly
I've tested this on ColdFusion MX7 and it works as expected. Dodged Appscan I did.

The goal is for the first request to be secure (and pass the scanning), so if this post covers that then it will solve the problem.
Correct me if I'm wrong, but it sounds like you need to redirect to HTTPS if a request comes in over HTTP. Can you not catch this with a URL rewriting rule, before the request is sent to ColdFusion at all?

Related

Coldfusion RESTful API, No Mapping Found error

This shouldn't be too hard to answer, but the discussions and documentation I've found can be rather unclear.
First of all, a little bit of information about my setup:
I'm on a hosted environment, and going through our ColdFusion admin group can be time-consuming. Therefore, I'm using the
restInitApplication function to register my RESTful web service.
My webroot folder (where my Application.cfm is located) is in
"E:\docs\wwwroot". I can only see, add, edit folders/files from
wwwroot down. I have no idea what's in "e:\docs". I believe that up
above where I cannot see there is another Application.cfm that sets
such things as the serverType (development, staging, or production),
that we (and other ColdFusion sites hosted on this server) use in
various places in our application code.
My pdfRestfulAPI.cfc (the component containing my webservice function) is in this folder,
"e:\docs\wwwroot\RESTservices". My component code looks like this:
<cfcomponent rest="true" >
<cffunction name="pdfconvert" access="remote" returntype="binary"
output="false" produces="application/xml" method="get" >
<cfargument name="sourceWebPageURL" type="string" >
<cfset pdfDoc = "" >
<cfdocument name="pdfDoc"
format="PDF"
src="#sourceWebPageURL#"
saveAsName="sample.pdf" >
</cfdocument>
<cfreturn #pdfDoc#>
</cffunction>
</cfcomponent>
The function itself is not an issue. It just converts a web page to pdf--pass a URL, get a PDF version of that web page. When I set it up as non-RESTful API (SOAP/xml) it works just fine.
In my Application.cfm, I am attempting to register my web service using the following code:
<cfset restInitApplication( getDirectoryFromPath(getCurrentTemplatePath())
& "RESTservices" ) >
This gives me a dir_path attribute of "E:\docs\wwwroot\RESTservices", which seems correct to me. I've omitted the optional mapping_name attribute. When the documentation says that this "can be anything", that is not helpful.
The error that I get in my Application.cfm reads:
coldfusion.rest.RestAppAdapter$InvalidApplicationException: No mapping
found for path E:\docs\wwwroot\RESTservices
Hopefully, I've laid out the details in such a way that anyone could try this out and let me know what I'm doing wrong.
Thanks, everyone!

How to overwrite CFID/CFTOKEN in ColdFusion 10?

In order to logout an user, I always used the following lines:
<cfset structClear(SESSION)>
<cfcookie name="CFID" value="" expires="NOW">
<cfcookie name="CFTOKEN" value="" expires="NOW">
It clears the data kept in the session on runtime and resets/renews CFID and CFTOKEN.
It does still work on our old server (ColdFusion 8), but it does no longer work on our new server (ColdFusion 10). The reason this attempt fails in ColdFusion 10 is rather simple: Whenever I try to overwrite CFID or CFTOKEN (with <cfcookie>), the cookie is placed on the top domain, e.g.:
Cookie set via <cfcookie> on ColdFusion 10:
domain: .myserver.com
while ColdFusion places its session cookies on the actual (sub)domain:
Generated CFID/CFTOKEN by ColdFusion 10:
domain: mywebsite.myserver.com
The funny thing is: If I set something like:
<cfcookie name="TEST" value="..." expires="NEVER">
the cookie is correctly set with:
domain: mywebsite.myserver.com
And I can easily clear the cookie using:
<cfcookie name="TEST" value="" expires="NOW">
I tried to use the domain property, but this:
<cfcookie name="CFID" value="" domain="mywebsite.myserver.com" expires="NOW">
always ends up as:
domain: .mywebsite.myserver.com
(notice the dot in front) and thus is not recognized as the same cookie.
Another strange thing is, that using:
<cfcookie name="CFID" value="" expires="NOW">
will not just generate a cookie with the wrong domain, but is kept instead of deleted as expired.
I checked the server settings for cookies on the ColdFusion 10 machine and the property Disable updating ColdFusion internal cookies using ColdFusion tags/functions is not checked.
Can anyone help me with this strange case?
There has already been some in depth discussion about the behavior of <cfcookie> related to domains. The following posts mention that the workaround seems to be using <cfheader> to work with the cookies:
ColdFusion 10 CFCookie not honoring domain attribute
why doesn't cfcookie allow setting domain= to a subdomain for CFID/CFTOKEN?
After posting that question Henry actually entered a bug with Adobe on it:
https://bugbase.adobe.com/index.cfm?event=bug&id=3593673
You can add your comments/vote to the bug.
While I believe these references answer your questions regarding the <cfcookie> behavior that you are seeing, if you are only concerned with "expiring" the user's session then Scott's answer gives you a better way to invalidate the user's current session than manually setting the cookies.
In ColdFusion 10, you can use sessionInvalidate() to accomplish this. You will not need to worry about removing the cookies either.

Force coldfusion 8 to reload component cache?

ColdFusion 8 is caching my cfcs. Development is at a stand-still. I don't have access to the admin panel. What are my options?
1) Get access to CF Administrator.
Really. I wouldn't want to host anywhere where I didn't have control over this.
2) Programmatically clear the cache.
Using the Admin API:
createObject("component","cfide.adminapi.runtime").clearTrustedCache()
Of course, if you don't have access to the CFAdmin, you might not have access to this either, but is worth trying.
According to this blog entry from Ray Camden you'll need to login to the admin via the API before running the above command, which of course suggests it's not going to work without already having access.
<cfset API = createObject("component","cfide.adminapi.runtime") />
<cfset API.login(adminPassword="password") />
<cfset API.clearTrustedCache() />
I use application.cfc to clear all of the cfc cache.
<!--- *****************************************************************
Run before the request is processed
************************************************************--->
<cffunction name="onRequestStart" returnType="boolean" output="false">
<cfargument name="thePage" type="string" required="true">
<cfscript>
if (structKeyExists(url,'reinit')) {
structClear(application);
structClear(session);
onApplicationStart();
onSessionStart();
}
</cfscript>
<cfreturn true>
</cffunction>
The idea is to pass a url variable called "reinit". Whenever this variable is defined in the URL, the application is started.
In order to test this:
1. make a change to cfc
2. call a cfm page by xxx.cfm?reinit=1
3. observe the changes in the cfc are reflected.
hope it helps...
I know that this post is old, but I needed to do this for a (more) modern version of ColdFusion (2016) and the answer from Peter wouldn't work on CF 2016. Not looking to be the answer, just a footnote for newer versions of CF.
Here is a version that will work with CF 2016:
<cfscript>
variables['adminPW'] = "my cf admin password";
cfAdminAPIAdmin = createObject("component", "cfide.adminapi.administrator");
cfAdminAPIAdmin.login(variables.adminPW);
cfAdminAPIRuntime = createObject("component", "cfide.adminapi.runtime");
// clear the component and trusted (template) caches
cfAdminAPIRuntime.clearComponentCache();
cfAdminAPIRuntime.clearTrustedCache();
</cfscript>
Adobe appears to have separated the CF admin functionality from the runtime component. That's really the only difference. The version above shows how to clear the component cache too.
NOTE: I had been doing something very similar to CFNinja's answer, but one site (out of about 25 similar sites) just wouldn't clear the application scope components, the old version remained in a cache somehow.

Coldfusion uses wrong (cached?) variables at random

We have a dedicated server running CentOS and Coldfusion 8.
All cfmail email is routed through Google with cfmail and smtp.
Every now and then, when cfmail is used, the 'FROM' field uses an address from a totally different website.
For instance:
Use form on Site A
Get an email: "Subject: On Site A From: siteb#siteb.com"
Where the from is a completely different variable in another set of code on another part of the server- there is no reason it should see this.
On the other side, sometimes sending an email to sitea#sitea.com has email wind up in Site B inbox, a completely different Google account.
What causes this to happen? Some kind of memory/cache issue? Or is there a funky DNS record causing issue?
Example:
Application.cfm (starts with some UDF includes, and then):
<cfinvoke component="#request.componentPath#.variables" method="getGlobal" />
Variables.cfc (a lot of variables defined within, but here is the cfmail vars):
<cffunction name="getGlobal" access="public" output="false" returntype="void">
<cfscript>
request.siteEmail = "email#mysite.com";
request.siteMailServer = "smtp.gmail.com";
request.siteMailUsername = "root#mysite.com";
request.siteMailPassword = "[redacted]";
</cfscript>
</cffunction>
It sounds like it's possible it could be a var scoping issue, but we can't know for sure until you share some code...
Looks like you're running multiple sites? there's a setting in the CF caching page in admin to do with caching web server paths:
From http://help.adobe.com/en_US/ColdFusion/9.0/Admin/WSc3ff6d0ea77859461172e0811cbf3638e6-7ffc.html :
Disabling the cacheRealPath attribute To ensure that ColdFusion always returns pages from the correct server, disable Cache Web Server Paths in the Caching page of the ColdFusion Administrator. (When you use the multiserver configuration, set the cacheRealPath attribute to false for the ProxyService in the jrun_root/servers/servername/SERVER-INF/jrun.xml file.)
Might not be it, but it's at least quick to try out.

restart application without restarting server?

Is there a way to restart a ColdFusion application without restarting the entire server?
There are two ColdFusion applications running on a server and I only want to restart one of them.
If you are using Application.cfc, you can update it so that you can force a call to onApplicationStart() if something specific is passed in the url, or something similar. Simply place a check for that magic token in onRequestStart(), and call onApplicationStart() if it is.
If you are not, you can try #Marcos's suggestion. I'm not sure what ramifications that may have in your application. What I would suggest is actually renaming your application, so it starts as a new app.
If you're on CF9, run ApplicationStop() https://cfdocs.org/applicationstop
Here you go, my CF7/8 version of CF9's ApplicationStop. I believe this is thread safe, noting Sean's comment.
<cffunction name="ApplicationStop" returntype="boolean" output="false">
<cfif IsDefined('application')>
<cftry>
<!--- This is just in case there's no app scope but variables.application --->
<cfset CreateObject('java', 'coldfusion.runtime.ApplicationScopeTracker').cleanUp(application) />
<cfreturn true />
<cfcatch type="any"></cfcatch>
</cftry>
</cfif>
<cfreturn false />
</cffunction>
As mentioned by Henry, he's my blog post on the subject:
http://misterdai.wordpress.com/2010/06/14/cf-flag-application-to-run-onapplicationstart-part-2/
A less invasive way of ending your app is to temporarily set the ApplicationTimeout to something very short.
Here is an example from an application.cfc file where the app is set to timeout in 10 seconds, which is plenty short for making a change and then checking back:
<cfcomponent displayname="Application">
<cfscript>
this.name = "myAppName";
this.setclientcookies="yes";
this.sessionmanagement="yes";
this.sessiontimeout= CreateTimeSpan(0,0,60,0);
this.applicationTimeout= CreateTimeSpan(0,0,0,10);
</cfscript>
...
</cfcomponent>
You might need to limit the session, too. See this article by Ben Nadel for an in-depth look at Application and Session timeouts.
If you are using application.cfc, stick this at the top of your onRequestStart function:
<!--- RESET APP? --->
<cfif isdefined("url.reinit")>
<cfset OnApplicationStart()>
<cfset OnSessionStart()>
</cfif>
Then you can pass a url var to any cfm and the app will reset.
<cfset structClear(application) />
I usually put a reference to each user's session into a struct in my Application scope to monitor what's going on in the app. Maybe doing something similar in the Server scope could help here. Try:
<cfset server.runningApplications["myApp"] = Application />
Then you'd have a reference to the actual Application object outside the scope of that application. You could try all manner of destructive things to get rid of it. Try this at your own risk!!! And do it on a dev server before you do it on your production box. ;)
Use cfinvoke.
<cfinvoke method="onApplicationEnd" component="Application">
<cfinvokeargument name="ApplicationScope" value="#application#" />
</cfinvoke>