How to restrict a remote coldfusion function from being called directly? (AJAX)

时间:2016-08-31 18:46:26

标签: jquery ajax security coldfusion csrf

I have a Coldfusion server with several applications. Many of these applications use a generic set of component functions for both server-side rendering and AJAX calls. Let's call this generic component file:

serverfunctions.cfc

These functions are stored in a folder separate from other applications, although the component files in each of these applications (cf)include the generic component file as a template. Let's call these app-specific component file:

appfunctions.cfc

AJAX requests go to appfunctions.cfc even if they are for methods in serverfunctions.cfc. This cuts down on redundant code and also allows me to check for CSRF attacks in the application.cfc OnRequestStart method before processing the AJAX request.

However...

I would like to enforce a requirement that EVERY AJAX request has to go through the appfunctions.cfc component, and serverfunctions.cfc CANNOT be called directly from the client. This way, other programmers on this codebase are prevented from "accidentally" setting up AJAX calls without proper CSRF protection.

So far I have tried to adjust the access attribute on the remote functions but that only returns "403 - Forbidden".

2 个答案:

答案 0 :(得分:1)

从@ BradWood的评论中汲取灵感,我得到了答案。

tl; dr:为serverfunctions文件夹创建服务器映射,并从appfunctions组件扩展它。

正如问题中所述,我的目标是通过应用程序级组件强制执行服务器级功能的AJAX调用,以强制执行抢占式CSRF令牌检查(必须在应用程序会话级别完成并保留服务器 - 级别功能完全无状态),同时将每个应用程序的冗余代码保持在最低限度。

Ben Nadel撰写的博客文章帮助实现了这一切:http://www.bennadel.com/blog/2115-extending-the-application-cfc-coldfusion-framework-component-with-a-relative-path-proxy.htm

这是一个代码示例:

服务器/ serverfunctionsfolder / serverfunctions.cfc

<CFCOMPONENT>
<cffunction name="getAHatForYourCat" access="package" returntype="string" returnformat="plain">
  <cfargument name="cat" type="string" required="yes" default="cat">
  <cfreturn cat & " and a hat.">
</cffunction>
</CFCOMPONENT>

服务器/应用/ appfunctions.cfc

<CFCOMPONENT extends="/serverfunctionsfolder/serverfunctions">
<cffunction name="getAHatForYourCat" access="remote" returntype="string" returnformat="plain">
  <cfargument name="cat" type="string" required="yes" default="cat">
  <cfreturn Super.getAHatForYourCat(cat)>
</cffunction>
</CFCOMPONENT>

server / app / Application.cfc(OPTIONAL-ISH)

(这取决于你想怎么做。你可以在application.cfc中创建一个映射,如下例所示,尽管我最终在ColdFusion管理员中进行了映射。)

<cffunction name="onRequestStart">
    <cfset this.mappings['/serverfunctionsfolder'] = ExpandPath("../serverfunctionsfolder/")>
</cffunction>

服务器/应用/ appscript.js

function getACatAndAHat(cat)
{
  var saveUrl = "components/appfunctions.cfc?method=getAHatForYourCat";
  var saveData = {};
  saveData['cat'] = cat;
  $.ajax({
    type:"POST",
    url: saveUrl,
    data: saveData
  }).done(function(data) {
    alert(data);
  }).fail(function(data) {
     alert("Get a hat for your cat failed");
   });  
}

// Method call with this argument returns "A cat and a hat."
getACatAndAHat("A cat");

我没有包含生成反CSRF令牌的代码,将其添加到AJAX请求中,或者使用OnRequestStart验证令牌,因为实现可能会有所不同,并且与问题或答案不完全相关。

答案 1 :(得分:0)

这是如何设置辅助的,外部不可访问的功能:

<cffunction name="select" access="package" output="false" returnType="array">

这应该给出错误: 方法&#39;选择&#39;在组件D中:/wwwroot/mywebsite/restapi/v1/comp.cfc无法远程访问。

这是我从REST cfc

访问该受保护功能的方法
<cfinvoke component="comp" method="select" returnVariable="myobj">
    <cfinvokeargument name="scRow" value="#scRow#">
</cfinvoke>