Enhancing ColdFusion Script Protection - Security Series #10

From http://www.12robots.com/index.cfm/2008/9/9/Enhancing-ColdFusion-Script-Protection--Security-Series-10

So anyone that has ever turned on Script Protection has either been annoyed by something that it does, or by something that it doesn't do. For me, it was both. I recently spoke with someone at bFlex about it, and he was having some of the same issues I had had with ColdFusion Script Protection. So, I finally decided to dig into it and see what could be done.

 

The Problem

There are two problems with ColdFusion Script Protection:

 

 

  1. It covers too much
  2. It doesn't cover enough

 

Well, that weird, isn't it? Yes, it's true. Script Protection is too strong and too weak at the same time.

 

Too Strong

"Too strong" might no be exactly the right way to describe this behavior in script protection, but this behavior bugs me none-the-less.

 

Let's say that someone tries to inject some Cross-Site Scripting code into the comments section of your blog. Something like:

 


<script type="text/javascript>

alert("pown'd");
</script>

 

Well ColdFusion Script Protection would turn that little diddy into this:

 


<InvalidTag type="text/javascript>
alert("
pown'd");
</script>

 

That's exactly what we want. This part of script protection is great. It would do the same thing with the Object, Embed, Applet, and Meta tags.

Now, let's pretend that someone (maybe even me) wants to put something on my blog about Transfer-ORM configuration files. Which look like this:

 


<?xml version="1.0" encoding="UTF-8"?>
<objectDefinitions>

    <package name="pages">
        <InvalidTag name="page" table="pages">
            <id name="pageid" type="UUID" />
            <property name="pagename" type="string" nullable="false" />
            <property name="pagetitle" type="string" nullable="true" />
            ...
            
            <onetomany name="section" lazy="true">
                <link to="pages.section" column="fkpageid"/>
                <collection type="array">
                    <order property="sortno" order="asc"/>
                </collection>
            </onetomany>
        </object>
        
        ...
</objectDefinitions>
</transfer>

 

Well, you see that <objectDefinitions> tag? It has the pattern "<object" in it. That means Script Protection is gonna see it as a threat.

So my Transfer config example is going to look like this.

 


<?xml version="1.0" encoding="UTF-8"?>
<InvalidTagDefinitions>
...
</objectDefinitions>

 

That sucks. And since the <objectDefinitions> is harmless when displayed, there is no reason for it to get filter like this.

This is the same issue that I heard about at bFlex, though a different tag was being filtered.

 

Too Weak

ColdFusion Script Protection is also too weak. It does not catch enough troublesome scripts. One of the biggies that it doesn't get, and I really can't understand why, is <iframe>.

 

IFrames are incredibly dangerous and can be used for some pretty nefarious stuff. Granted, if you are properly escaping your user-generated output with HTMLEditFormat() this shouldn't be a concern, but it is a dangerous assumption to believe we are perfect. There may be some other tags or patterns we would like to see removed as well.

 

The Solution

So, it turns out that changing this behavior in ColdFusion Script Protection is pretty easy. There is an XML config file that contains patterns that are compared to the incoming data. If a match is made, then the replacement value is inserted. The patterns are simple Regular Expressions (RegEx).

 

So not being an expert in Regular Expressions, I asked Ben Nadel to help me figure this out. He helped me find the RegEx solution I needed very quickly. Thanks Ben!

In your ColdFusion installation you will find a /lib folder.

Windows users: C:/ColdFusion8/lib Mac Users: /Applications/ColdFusion/lib *nix: /opt/coldfusion/lib (I think)

In the /lib folder you will find a file called neo-security.xml. Near the bottom of this file you'll see something that looks like:

 


    <var name='CrossSiteScriptPatterns'>
        <struct type='coldfusion.server.ConfigMap'>
            <var name='</s*(object|embed|script|applet|meta)'>
                <string>
                    <InvalidTag
                </string>
            </var>
        </struct>
    </var>

 

What this is saying is, if you come across something that matches the RegEx Pattern "&lt;/s*(object|embed|script|applet|meta)", then replace those characters with &lt;InvalidTag.

Now, normally I would think that this is fine, but like I said, I do not want <objectDefinition to be turned into <InvalidTagDefinition.

So, how do I stop this? Well first, I take the "object" text out of the existing patterns and make a new pattern with it. And I add a little extra.

 


    <var name='CrossSiteScriptPatterns'>
        <struct type='coldfusion.server.ConfigMap'>
            <var name='</s*(embed|script|applet|meta)'>
                <string>
                    <InvalidTag
                </string>
            </var>
            <var name='</s*object(?!Definitions)'>
                <string>
                    <InvalidTag
                </string>
            </var>
        </struct>
    </var>

 

So here, I have added another pattern for the XSS filter to try to match. This patterns says to match <object unless it is <objectDefinitions.

This could also be expanded to include additional patterns that begin with "<object".

 


    <var name='CrossSiteScriptPatterns'>
        <struct type='coldfusion.server.ConfigMap'>
            <var name='</s*(embed|script|applet|meta)'>
                <string>
                    <InvalidTag
                </string>
            </var>
            <var name='</s*object(?!(Definitions|ive))'>
                <string>
                    <InvalidTag
                </string>
            </var>
        </struct>
    </var>

 

Here, it will not match "<objectDefinitions" or "<objective".

Very nice.

Now to discuss adding the <iframe> tag. This is actually even easier.

 


    <var name='CrossSiteScriptPatterns'>
        <struct type='coldfusion.server.ConfigMap'>
            <var name='</s*(embed|script|applet|meta)'>
                <string>
                    <InvalidTag
                </string>
            </var>
            <var name='</s*object(?!(Definitions|ive))'>
                <string>
                    <InvalidTag
                </string>
            </var>
            <var name='</s*iframe'>
                <string>
                    <InvalidTag
                </string>
            </var>
        </struct>
    </var>

 

Simply by adding another <var> to the <struct> I can add this pattern "&lt;/s*iframe" which will find <iframe.

UPDATE: I forgot to mention in this post, after you change the neo-security.xml that you must restart the ColdFusion Application Server for the changes to take effect.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章