为防止跨站点脚本(XSS)我正在使用OWASP推荐的ESAPI (Enterprise Security API)。 The esapi.jar file has been included with prior version of ColdFusion但在CF10中,您现在可以轻松调用其中一些有用的功能:encodeForJavascript()
,encodeForHTML()
,encodeForURL()
,encodeForCSS()
和encodeForHTMLAttribute()
。
我遇到encodeForJavascript()
的麻烦,我正在失去反击......
<cfoutput>
<cfif isDefined("url.name")>
<!--- Here is the problem, this is identical to the original ascii32to126 string except for one char is missing, the backslash between the brackets ...Z[]... --->
#url.name#
<cfabort>
</cfif>
<!---
ASCII 32 thru 126
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
In the line below I double up on the double-quotes and pounds in order to get the cfset to work
--->
<cfset ascii32to126 = "!""##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<script>
function locateTo(value)
{
window.location='thisPage.cfm?name='+encodeURIComponent(value);
//alert('thisPage.cfm?name='+encodeURIComponent(value));
}
locateTo('#encodeForJavaScript(ascii32to126)#');
</script>
</cfoutput>
我首先调用encodeForJavaScript()
,因为我们处于JavaScript上下文中。
然后我致电encodeURIComponent()
以确保网址构建正确。
一切正常但在结果页面上我丢失了反斜杠\
。我在这里缺少什么?
(是的,我知道我还必须保护输出#url.name#
的位置。对于这个实验,我没有这样做,因为我需要查看源以查看字符串是否与原始字符串匹配。)
** UPDATE ** - 我正在运行ColdFusion 10并应用了所有最新的补丁。问题似乎出现在encodeForJavaScript()
。
也因JSStringFormat()
而失败。这样做表明两者都缺少反斜杠......
<cfset ascii32to126 = "!""##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<cfoutput>
#encodeForHTML(encodeForJavaScript(ascii32to126))#
<br><br>
#encodeForHTML(JSStringFormat(ascii32to126))#
</cfoutput>
答案 0 :(得分:1)
FWIW,我们一直在使用所有的encodeForX函数超过一年,只有在开发人员使用错误的上下文时才会遇到问题。我们已经严格禁止使用HTMLEditFormat,并且在整天运行构建时,会对Jenkins服务器进行检查(以及其他非法函数和标记)。
您正在为JavaScript编码字符串,然后将其编码为URL。我相信你应该首先编码URL,然后编码JavaScript。当我将输出与未编码的字符串进行比较时,似乎没有任何丢失的字符。
<cfoutput>
<cfif isDefined("url.name")>
<!--- Here is the problem, this is identical to the original ascii32to126 string except for one char is missing, the backslash between the brackets ...Z[]... --->
#url.name#
<cfabort>
</cfif>
<!---
ASCII 32 thru 126
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
In the line below I double up on the double-quotes and pounds in order to get the cfset to work
--->
<!--- Using Chr() to bypass character escaping. --->
<cfset ascii32to126 = "!#chr(34)##chr(35)#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<cfdump var="#ascii32to126#" />
<script>
function locateTo(a, b) {
console.log(a); // 1. JavaScript Encoded.
console.log(b); // 2. URL encoded, then JavaScript encoded.
console.log(decodeURIComponent(b));// 3. Matches JavaScript encoded.
console.log( 'thisPage.cfm?name=' + b ); // 4. Correct string.
}
locateTo('#encodeForJavaScript(ascii32to126)#', '#encodeForJavaScript(encodeForURL(ascii32to126))#');
</script>
</cfoutput>
控制台输出
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
thisPage.cfm?name=%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
答案 1 :(得分:0)
我们有自己的自定义编码函数ddj()...
<!---
Author: @Brian McGinity
custom version of jsStringFormat/encodeForJavaScript
--->
<cffunction name="ddj" returntype="string" output="false">
<cfargument name="temp" required="yes" type="string">
<!---
<cfset var z = jsStringFormat(arguments.temp)>
<cfreturn z>
--->
<cfset var buf = CreateObject("java", "java.lang.StringBuffer")>
<cfset var len = Len(arguments.temp)>
<cfset var char = "">
<cfset var charcode = 0>
<cfset var bad = ' >%}\~];?@&<##{|^[`/:=$+"' & "'">
<cfset buf.ensureCapacity(JavaCast("int", len+40))>
<cfif NOT len><cfreturn arguments.temp></cfif>
<cfloop from="1" to="#len#" index="xmlIdx">
<cfset char = mid(arguments.temp,xmlIdx,1)>
<cfset charcode = asc(char)>
<cfif charcode LT 32 or charcode gt 126>
<cfset buf.append(JavaCast("string", ""))>
<cfelse>
<cfif find(char, bad) gt 0>
<cfset buf.append(JavaCast("string", "\u00" & right("0" & formatBaseN(charcode,16),2) ))>
<cfelse>
<cfset buf.append(JavaCast("string", char))>
</cfif>
</cfif>
</cfloop>
<cfreturn buf.toString()>
</cffunction>
使用ddj()
我可以将ascii32to126字符串传递给函数,然后在其上执行encodeURIComponent
,然后找到页面并打印它,字符串完全相同。似乎工作得很好。但是这样做我首先编码JS,然后是URL编码。这似乎不对。我一直认为它必须与(see here)相反。所以我想弄明白我是否可以打破它。以下是似乎有用的测试用例......
<cfoutput>
<cfif isDefined("url.name")>
#url.name#
<cfabort>
</cfif>
<!--- !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ --->
<cfset ascii32to126 = "!""##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<script>
function goToUrl(value)
{
window.location='thisPage.cfm?name='+encodeURIComponent(value);
//alert('thisPage.cfm?name='+encodeURIComponent(value));
}
goToUrl('#ddj(ascii32to126)#');
</script>
</cfoutput>
答案 2 :(得分:0)
(2年以后)似乎已经由Adobe或ESAPI人员修复。包括反斜杠在内的所有字符都会保留。我现在正在运行这些版本......
服务器产品:ColdFusion
版本:11,0,09,299201
Tomcat版本:7.0.68.0
版本:开发人员
操作系统:Windows 10
操作系统版本:10.0
更新级别:C:/ColdFusion11/cfusion/lib/updates/chf11000009.jar
Adobe Driver:5.1.3(Build 000094)
Java版本:1.8.0_91
Java供应商:Oracle Corporation