如何限制直接调用远程 Coldfusion 函数? (AJAX)
How to restrict a remote coldfusion function from being called directly? (AJAX)
我有一个带有多个应用程序的 Coldfusion 服务器。其中许多应用程序都使用一组通用的组件函数来进行服务器端呈现和 AJAX 调用。我们称这个通用组件文件为:
serverfunctions.cfc
尽管每个应用程序 (cf) 中的组件文件都包含通用组件文件作为模板,但这些功能存储在与其他应用程序分开的文件夹中。我们将这些特定于应用程序的组件文件称为:
appfunctions.cfc
AJAX 请求转到 appfunctions.cfc,即使它们是针对 serverfunctions.cfc 中的方法。这减少了冗余代码,还允许我在处理 AJAX 请求之前检查 application.cfc OnRequestStart 方法中的 CSRF 攻击。
然而...
我想强制要求每个 AJAX 请求都必须通过 appfunctions.cfc 组件,并且 serverfunctions.cfc 不能直接从客户端调用。这样,此代码库上的其他程序员将无法 "accidentally" 在没有适当的 CSRF 保护的情况下设置 AJAX 调用。
到目前为止,我已经尝试调整远程功能的访问属性,但只有 returns“403 - 禁止访问”。
这是外部不可访问的次要功能的设置方式:
<cffunction name="select" access="package" output="false" returnType="array">
这应该给出错误:
组件D中的方法'select':/wwwroot/mywebsite/restapi/v1/comp.cfc无法远程访问
这就是我从 REST cfc 访问该受保护函数的方式
<cfinvoke component="comp" method="select" returnVariable="myobj">
<cfinvokeargument name="scRow" value="#scRow#">
</cfinvoke>
从@BradWood 的评论中汲取灵感,我得出了答案。
tl;dr:为 serverfunctions 文件夹创建一个服务器映射,并从 appfunctions 组件扩展它。
如问题中所述,我的目标是通过应用程序级组件强制 AJAX 调用服务器级功能,以强制执行抢占式 CSRF 令牌检查(必须在应用程序会话中完成级并保持服务器级功能完全无状态),同时将每个应用程序的冗余代码保持在最低限度。
Ben Nadel 的博客 post 将这一切整合在一起:http://www.bennadel.com/blog/2115-extending-the-application-cfc-coldfusion-framework-component-with-a-relative-path-proxy.htm
这是一个代码示例:
server/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>
server/app/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(可选-ISH)
(这取决于你想怎么做。你可以在 application.cfc 中创建一个映射,如下所示,尽管我最终在 ColdFusion 管理员中创建了映射。)
<cffunction name="onRequestStart">
<cfset this.mappings['/serverfunctionsfolder'] = ExpandPath("../serverfunctionsfolder/")>
</cffunction>
server/app/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 验证令牌的代码,因为实现可能会有所不同并且它与问题不完全相关或回答。
我有一个带有多个应用程序的 Coldfusion 服务器。其中许多应用程序都使用一组通用的组件函数来进行服务器端呈现和 AJAX 调用。我们称这个通用组件文件为:
serverfunctions.cfc
尽管每个应用程序 (cf) 中的组件文件都包含通用组件文件作为模板,但这些功能存储在与其他应用程序分开的文件夹中。我们将这些特定于应用程序的组件文件称为:
appfunctions.cfc
AJAX 请求转到 appfunctions.cfc,即使它们是针对 serverfunctions.cfc 中的方法。这减少了冗余代码,还允许我在处理 AJAX 请求之前检查 application.cfc OnRequestStart 方法中的 CSRF 攻击。
然而...
我想强制要求每个 AJAX 请求都必须通过 appfunctions.cfc 组件,并且 serverfunctions.cfc 不能直接从客户端调用。这样,此代码库上的其他程序员将无法 "accidentally" 在没有适当的 CSRF 保护的情况下设置 AJAX 调用。
到目前为止,我已经尝试调整远程功能的访问属性,但只有 returns“403 - 禁止访问”。
这是外部不可访问的次要功能的设置方式:
<cffunction name="select" access="package" output="false" returnType="array">
这应该给出错误: 组件D中的方法'select':/wwwroot/mywebsite/restapi/v1/comp.cfc无法远程访问
这就是我从 REST cfc 访问该受保护函数的方式
<cfinvoke component="comp" method="select" returnVariable="myobj">
<cfinvokeargument name="scRow" value="#scRow#">
</cfinvoke>
从@BradWood 的评论中汲取灵感,我得出了答案。
tl;dr:为 serverfunctions 文件夹创建一个服务器映射,并从 appfunctions 组件扩展它。
如问题中所述,我的目标是通过应用程序级组件强制 AJAX 调用服务器级功能,以强制执行抢占式 CSRF 令牌检查(必须在应用程序会话中完成级并保持服务器级功能完全无状态),同时将每个应用程序的冗余代码保持在最低限度。
Ben Nadel 的博客 post 将这一切整合在一起:http://www.bennadel.com/blog/2115-extending-the-application-cfc-coldfusion-framework-component-with-a-relative-path-proxy.htm
这是一个代码示例:
server/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>
server/app/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(可选-ISH)
(这取决于你想怎么做。你可以在 application.cfc 中创建一个映射,如下所示,尽管我最终在 ColdFusion 管理员中创建了映射。)
<cffunction name="onRequestStart">
<cfset this.mappings['/serverfunctionsfolder'] = ExpandPath("../serverfunctionsfolder/")>
</cffunction>
server/app/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 验证令牌的代码,因为实现可能会有所不同并且它与问题不完全相关或回答。