1

为了防止跨站点脚本(XSS),我使用了 OWASP 推荐的ESAPI(企业安全 API)esapi.jar 文件已包含在 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。

一切正常,但在结果页面上我丢失了反斜杠\。我在这里想念什么?

(是的,我知道我还必须保护我的输出位置#url.name#。对于这个实验,我没有这样做,因为我需要查看源以查看字符串是否与原始字符串匹配。)

**更新** - 我正在运行 ColdFusion 10,并应用了所有最新的补丁。问题似乎出在encodeForJavaScript().

也失败了JSStringFormat()。这样做表明两者都缺少反斜杠......

<cfset ascii32to126 = "!""##$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~">
<cfoutput>
    #encodeForHTML(encodeForJavaScript(ascii32to126))#
    <br><br>
    #encodeForHTML(JSStringFormat(ascii32to126))#
</cfoutput>
4

3 回答 3

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 
于 2014-04-30T22:12:45.250 回答
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 编码。这似乎不对。我一直认为它必须是相反的方式见这里。所以我想弄清楚我是否可以打破它。这是似乎有效的测试用例...

<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>
于 2014-04-30T23:19:58.807 回答
0

(2 年后)它似乎已被 Adob​​e 或 ESAPI 人员修复。保留包括反斜杠在内的所有字符。我现在正在运行这些版本...

服务器产品:ColdFusion

版本:11,0,09,299201

Tomcat 版本:7.0.68.0

版本:开发者

操作系统:Windows 10

操作系统版本:10.0

更新级别:C:/ColdFusion11/cfusion/lib/updates/chf11000009.jar

Adobe 驱动程序:5.1.3(内部版本 000094)

Java版本:1.8.0_91

Java 供应商:甲骨文公司

于 2016-07-27T18:55:08.287 回答