Web Trenches

ColdFusion/CFML and Access-Control-Allow-Origin

As a defense against cross-site ccripting attacks (XSS), modern browsers now disallow ajax calls made across domains by default.  You can enable certain sites to make ajax calls to your site by adding the Access-Control-Allow-Origin header to the page.   For example, if your page at http://www.mydomain.com/main-page needs to make an ajax call to http://www.otherdomain.com/ajax-page, you would add the Access-Control-Allow-Origin header to your ajax-page like this:

<cfheader name="Access-Control-Allow-Origin" value="http://www.mydomain.com" />

But what if you have an ajax page that MULTIPLE domains need to use?  The header only supports a single domain.  Some people approach this problem with the * wildcard.

<cfheader name="Access-Control-Allow-Origin" value="*" />

The problem with this approach is that it exposes you to XSS, which really defeats the purpose of this security feature to begin with.  The better approach is to look for the Origin header and compare that header to a list of allowed domains for your script.  Then, only display the one that the Origin needs.  The following function accomplishes that.

<cffunction name="addAllowOrigin">
<cfargument name="domainsallowed" />
<cfset httpdata = getHttpRequestData(false) />
<cfif structKeyExists(httpdata.headers,'Origin') AND ListFindNoCase(arguments.domainsallowed,httpdata.headers.origin)>
<cfheader name="Access-Control-Allow-Origin" value="#httpdata.headers.origin#" />

The function gets the details of the HTTP request being made, then looks at the Origin header.  If that Origin header is in the list of allowed domains, it issues the needed Access-Control-Allow-Origin header back to the request so that it is allowed.

Here’s an example of a call to this…


If the Ajax request is coming from any of the listed domains, it will be allowed.  Note that there is a difference between http:// and https://.  You’ll need to add both variations if you want to allow secure and non-secure calls.

Leave a Reply

Your email address will not be published. Required fields are marked *