b1nary0mega
6/8/2015 - 1:15 PM

From http://www.bennadel.com/blog/932-ask-ben-handling-errors-with-coldfusion-cferror.htm

<!---
    Define function that will recursively search a
    struct and it's nested elements for keys that should
    be considered secure and blacked out.
--->
<cffunction
    name="MakeStructSecure"
    access="public"
    returntype="any"
    output="false"
    hint="Does a very cursory job of cleaning up a struct by blacking out secure information.">
 
    <!--- Define argumets. --->
    <cfargument
        name="Struct"
        type="struct"
        required="true"
        hint="The struct we are going to clean."
        />
 
    <cfargument
        name="Depth"
        type="numeric"
        required="false"
        default="1"
        hint="The depth of the current search - this will stop the function from looping infinitely."
        />
 
    <!--- Define the local scope. --->
    <cfset var LOCAL = StructNew() />
 
    <!---
        Check to see if we have reached our max depth
        for this search.
    --->
    <cfif (ARGUMENTS.Depth GTE 5)>
 
        <!---
            You're going too deep, it hurts! We might be
            looping in a circular struct reference.
        --->
        <cfreturn />
 
    </cfif>
 
 
    <!---
        ASSERT: If we have made it this far, then we have
        to check all the struct keys at this level.
    --->
 
    <!---
        Define the list of keys that would be considered
        to hold secure data.
    --->
    <cfsavecontent variable="LOCAL.SecureKeys">
        CreditCard
        CCNumber
        CCNum
        ExpirationDate
        Expry
        ExpDate
        CCExp
    </cfsavecontent>
 
 
    <!---
        Loop over the struct looking for keys that would
        flag secure data to be removed.
    --->
    <cfloop
        item="LOCAL.Key"
        collection="#ARGUMENTS.Struct#">
 
        <!---
            Check to see if the key is to be considered
            secure AND that the value in it is simple.
        --->
        <cfif (
            FindNoCase( LOCAL.Key, LOCAL.SecureKeys ) AND
            IsSimpleValue( ARGUMENTS.Struct[ LOCAL.Key ] )
            )>
 
            <!--- Black out value. --->
            <cfset ARGUMENTS.Struct[ LOCAL.Key ] = RepeatString(
                "*",
                Len( ARGUMENTS.Struct[ LOCAL.Key ] )
                ) />
 
        <!---
            Check to see if this key is a struct that we
            might have to search through.
        --->
        <cfelseif IsStruct( ARGUMENTS.Struct[ LOCAL.Key ] )>
 
            <!---
                Recurse through this one. Be sure to send
                through a new depth value so we don't loop
                forever.
            --->
            <cfset MakeStructSecure(
                Struct = ARGUMENTS.Struct[ LOCAL.Key ],
                Depth = (ARGUMENTS.Depth + 1)
                ) />
 
        </cfif>
 
    </cfloop>
 
 
    <!--- Return out. --->
    <cfif (ARGUMENTS.Depth EQ 1)>
 
        <!--- Return the cleaned struct. --->
        <cfreturn ARGUMENTS.Struct />
 
    <cfelse>
        <cfreturn />
    </cfif>
</cffunction>