在Adobe ColdFusion 10开发指南中,在点对点通信中使用WebSocket时,<cfwebsocket>
创建的javascript对象mysocket
可以调用invoke()
方法,该方法可以从javascript中实际调用Any CFC上的Any public方法。
这是如何不是安全风险的?cfc/函数应如何防止被websocket调用?
1.创建CFM页面索引.CFM。
<script type="text/javascript"> function msgHandler(msgobj){ var txt = document.getElementById("myDiv"); var message = ColdFusion.JSON.encode(msgobj); txt.innerHTML += message + "<br >" + "<br>"; } function invokecfcfn(){ var fname= document.getElementById("fnname").value; if (fname == "f2") { alert("f2 selected"); mysocket.invoke("mycfc", "f2", ["echo"]); } else mysocket.invoke("mycfc", fname); } </script> <cfwebsocket name="mysocket" onmessage="msgHandler"/> <form> <select id="fnname"> <option>f1</option> <option>f2</option> <option>f3</option> </select> <input id="invokefn" name="invokefn" value="Invoke CFC function " type="button" onclick="invokecfcfn();"> <div id="myDiv"> </div> </form>
2.创建一个包含从客户端页面调用的函数的CFC mycfg.CFC
<cfcomponent> <cffunction name="f1" > <cfreturn "Message returned from f1"> </cffunction> <cffunction name="f2" returntype="string" > <cfargument name="arg1" type="string" required="true" > <cfset msg= "Message from wsssendmessage of f2 which you called with arg " & arg1> <cfset wssendMessage(msg)> <cfreturn "Message returned from f2"> </cffunction> <cffunction name="f3" > <cfthread action="run" name="t1" > <cfloop index="i" from="1" to="10"> <cfset sleep(20000)> <cfset wssendMessage("Message #i# from wsssendmessage of f3 #now()#")> </cfloop> </cfthread> <cfreturn "Thread initiated in f3"> </cffunction> </cfcomponent>
编辑:不是任何函数,私有函数返回:
{
"clientid":39550088,
"ns":"coldfusion.websocket.channels",
"reqType":"invoke",
"code":4001,
"type":"response",
"msg":"The method f1 was not found in component mycfc.cfc."
}
更新:
我尝试将mycfc.cfc
移动到/com
(在webroot之外),并添加到/com
的映射,这些函数可以成功调用。
更新:2013年7月3日
Adobe产品安全事件响应小组(PSIRT)知道并积极与ColdFusion产品团队合作发布修复程序。
http://blogs.coldfusion.com/post.cfm/coldfusion-10-websocket-vulnerebility
更新:2013年7月9日
Adobe发布了适用于Windows的ColdFusion 10的安全修补程序,Macintosh和Linux。此修补程序解决了一个漏洞(CVE-2013-3350)可能允许攻击者调用公共方法关于使用WebSockets的ColdFusion组件(CFC)。
http://www.adobe.com/support/security/bulletins/apsb13-19.html
我不认为你可以用ColdFusion来解决这个问题(更新:这是在ColdFusion10.0.11发布之前写的;这个问题现在已经在10.0.11之前解决了)。我不认为Bruce基于CFML的答案在现实世界中真的可行,尽管它或它的变体会起作用。
我可能会回到使用防火墙规则:web套接字请求来自特定的端口,所以你可以有一套关于该端口上请求的规则,以及哪些方法可以通过它
这不是一个很好的解决方案,但考虑到目前的情况,这可能是最有利的。
我在对你最初问题的评论中指出了我对CF方面的研究,但最好从这里链接到:"Web套接字安全问题:风险评估和发现"
Coldfusion 10 websockets invoke功能在经过实际测试和对新文档页面和其他项目的进一步调查后,对我来说似乎已经崩溃了(这件事很复杂!)。我花了一个多小时试图在调用的函数运行之前执行一些东西。我不能!
这里记录了一些新的"通道侦听器功能":http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSe61e35da8d318518767eb3aa135858633ee-7ff9.html
然而,文档清楚地指出,"invoke"特性没有监听器函数。在运行invoke时,Application.cfc或cfc侦听器似乎根本不会对每个请求执行。
这似乎是一个设计缺陷。该语言需要更多的事件侦听器,否则如果不为应用程序中的每个函数添加安全性,就无法使用websocket。
每个函数中的安全性可以像下面的代码一样完成,但修改应用程序中的每个函数并不是很实用:
<cfscript>
local.meta=GetMetaData(this[url.method]);
if(not structkeyexists(local.meta, 'access') or local.meta.access NEQ 'remote'){
throw("Function access must be set to remote.");
}
</cfscript>
您也可以考虑在Coldfusion前面使用web服务器代理,并使用正则表达式来验证请求信息,这样就只需要在公共websocket端口上打开应用程序的websocket部分。Nginx 1.4+现在支持websocket代理:http://nginx.org/en/docs/http/websocket.html注意:我还没有使用nginx-websocket代理进行测试。如果它有效,这将是一个简单得多的解决方案。
Adobe发布了适用于Windows的ColdFusion 10的安全修补程序,Macintosh和Linux。此修补程序解决了一个漏洞(CVE-2013-3350)可能允许攻击者调用公共方法关于使用WebSockets的ColdFusion组件(CFC)。
http://www.adobe.com/support/security/bulletins/apsb13-19.html
在应用Update 11之后调用公共方法将返回"code":4001
&"msg":"The method f1 in component mycfc cannot be accessed remotely."
对于Javascript或任何其他客户端来说,能够在任何CFC上调用任何公共方法肯定不是安全风险。这是您选择公开为公共的接口的预期行为。为了解决这个问题,ColdFusion团队必须回到他们最初的Websocket设计并重新进行。