Created
September 27, 2010 21:03
-
-
Save rip747/599828 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 8922990286e83f9d9307d07dbc286b7d4ecb348e Mon Sep 17 00:00:00 2001 | |
From: Tony Petruzzi <[email protected]> | |
Date: Mon, 27 Sep 2010 16:59:40 -0400 | |
Subject: [PATCH] saving work | |
--- | |
wheels/controller/layouts.cfm | 2 +- | |
wheels/controller/rendering.cfm | 1 + | |
wheels/global/appfunctions.cfm | 2 + | |
wheels/global/cfml.cfm | 18 +++++ | |
wheels/global/functions.cfm | 1 + | |
wheels/global/sanitize.cfm | 81 ++++++++++++++++++++++++ | |
wheels/tests/_assets/views/test/_xssAttack.cfm | 1 + | |
wheels/tests/global/sanitize/rendering.cfc | 21 ++++++ | |
wheels/tests/global/sanitize/values.cfc | 34 ++++++++++ | |
9 files changed, 160 insertions(+), 1 deletions(-) | |
create mode 100644 wheels/global/sanitize.cfm | |
create mode 100644 wheels/tests/_assets/views/test/_xssAttack.cfm | |
create mode 100644 wheels/tests/global/sanitize/rendering.cfc | |
create mode 100644 wheels/tests/global/sanitize/values.cfc | |
diff --git a/wheels/controller/layouts.cfm b/wheels/controller/layouts.cfm | |
index 1e897db..54032be 100644 | |
--- a/wheels/controller/layouts.cfm | |
+++ b/wheels/controller/layouts.cfm | |
@@ -116,7 +116,7 @@ | |
{ | |
loc.include = loc.include & "/" & "layout.cfm"; | |
} | |
- loc.returnValue = $includeAndReturnOutput($template=loc.include); | |
+ loc.returnValue = $includeAndReturnOutput($template=loc.include, $sanitize=true); | |
} | |
else | |
{ | |
diff --git a/wheels/controller/rendering.cfm b/wheels/controller/rendering.cfm | |
index 1e01bf9..22c82b8 100644 | |
--- a/wheels/controller/rendering.cfm | |
+++ b/wheels/controller/rendering.cfm | |
@@ -377,6 +377,7 @@ | |
<cfargument name="$type" type="string" required="true"> | |
<cfscript> | |
var loc = {}; | |
+ arguments.$sanitize = true; | |
if (arguments.$type == "partial") | |
{ | |
if (StructKeyExists(arguments, "query") && IsQuery(arguments.query)) | |
diff --git a/wheels/global/appfunctions.cfm b/wheels/global/appfunctions.cfm | |
index 1d0949f..4eb6c61 100644 | |
--- a/wheels/global/appfunctions.cfm | |
+++ b/wheels/global/appfunctions.cfm | |
@@ -2,10 +2,12 @@ | |
<cfinclude template="cfml.cfm"> | |
<cfinclude template="internal.cfm"> | |
<cfinclude template="public.cfm"> | |
+ <cfinclude template="sanitize.cfm"> | |
<cfinclude template="../../events/functions.cfm"> | |
<cfelse> | |
<cfinclude template="wheels/global/cfml.cfm"> | |
<cfinclude template="wheels/global/internal.cfm"> | |
<cfinclude template="wheels/global/public.cfm"> | |
+ <cfinclude template="wheels/global/sanitize.cfm"> | |
<cfinclude template="events/functions.cfm"> | |
</cfif> | |
\ No newline at end of file | |
diff --git a/wheels/global/cfml.cfm b/wheels/global/cfml.cfm | |
index 33b4b7b..c48d295 100644 | |
--- a/wheels/global/cfml.cfm | |
+++ b/wheels/global/cfml.cfm | |
@@ -129,13 +129,31 @@ | |
<cffunction name="$includeAndReturnOutput" returntype="string" access="public" output="false"> | |
<cfargument name="$template" type="string" required="true"> | |
+ <cfargument name="$sanitize" type="boolean" required="true" default="false"> | |
<cfset var loc = {}> | |
+ | |
+ <cfset var _orgArguments = ""> | |
+ <cfset var _orgVariables = ""> | |
+ | |
+ <cfif arguments.$sanitize> | |
+ <cfset _orgArguments = duplicate(arguments)> | |
+ <cfset _orgVariables = duplicate(variables)> | |
+ <cfset arguments = sanitize(arguments)> | |
+ <cfset variables = sanitize(variables)> | |
+ </cfif> | |
+ | |
<cfif StructKeyExists(arguments, "$type") AND arguments.$type IS "partial"> | |
<!--- make it so the developer can reference passed in arguments in the loc scope if they prefer ---> | |
<cfset loc = arguments> | |
</cfif> | |
+ | |
<!--- we prefix returnValue with "wheels" here to make sure the variable does not get overwritten in the included template ---> | |
<cfsavecontent variable="loc.wheelsReturnValue"><cfoutput><cfinclude template="../../#LCase(arguments.$template)#"></cfoutput></cfsavecontent> | |
+ | |
+ <cfif arguments.$sanitize> | |
+ <cfset variables = _orgVariables> | |
+ </cfif> | |
+ | |
<cfreturn loc.wheelsReturnValue> | |
</cffunction> | |
diff --git a/wheels/global/functions.cfm b/wheels/global/functions.cfm | |
index 8b0da07..c38ae13 100644 | |
--- a/wheels/global/functions.cfm | |
+++ b/wheels/global/functions.cfm | |
@@ -1,4 +1,5 @@ | |
<cfinclude template="cfml.cfm"> | |
<cfinclude template="internal.cfm"> | |
<cfinclude template="public.cfm"> | |
+<cfinclude template="sanitize.cfm"> | |
<cfinclude template="../../events/functions.cfm"> | |
\ No newline at end of file | |
diff --git a/wheels/global/sanitize.cfm b/wheels/global/sanitize.cfm | |
new file mode 100644 | |
index 0000000..daf2b84 | |
--- /dev/null | |
+++ b/wheels/global/sanitize.cfm | |
@@ -0,0 +1,81 @@ | |
+<cffunction name="sanitize" access="public" returntype="any" output="false"> | |
+ <cfargument name="scope" type="any" required="true"> | |
+ <cfscript> | |
+ var loc = {}; | |
+ if (IsArray(arguments.scope)) | |
+ { | |
+ loc.iEnd = ArrayLen(arguments.scope); | |
+ for (loc.i = 1; loc.i lte loc.iEnd; loc.i++) | |
+ { | |
+ try | |
+ { | |
+ arguments.scope[loc.i] = sanitize(arguments.scope[loc.i]); | |
+ } | |
+ catch(Any e) | |
+ { | |
+ $dump(arguments.scope[loc.i]); | |
+ } | |
+ } | |
+ } | |
+ else if (IsStruct(arguments.scope)) | |
+ { | |
+ for (loc.item in arguments.scope) | |
+ { | |
+ try | |
+ { | |
+ if (Left(loc.item, 1) != "$" && !IsCustomFunction(arguments.scope[loc.item])) | |
+ { | |
+ //$dump(loc.item); | |
+ arguments.scope[loc.item] = sanitize(arguments.scope[loc.item]); | |
+ } | |
+ } | |
+ catch(Any e) | |
+ { | |
+ $dump(loc.item, false); | |
+ $dump(arguments.scope); | |
+ } | |
+ } | |
+ } | |
+ else if (IsQuery(arguments.scope)) | |
+ { | |
+ arguments.scope = sanitizeQuery(arguments.scope); | |
+ } | |
+ if (IsSimpleValue(arguments.scope)) | |
+ { | |
+ arguments.scope = XMLFormat(arguments.scope); | |
+ } | |
+ </cfscript> | |
+ <cfreturn arguments.scope> | |
+</cffunction> | |
+ | |
+<cffunction name="sanitizeQuery" returntype="query" access="public" output="false" hint="Encodes all string values within a query to help protect against cross-site scripting attacks."> | |
+ <cfargument name="qry" type="query" required="true"> | |
+ <cfscript> | |
+ var loc = {}; | |
+ loc.stringCols = $getStringColumnsListFromQuery(arguments.qry); | |
+ for (loc.row=1; loc.row lte arguments.qry.recordcount; loc.row++) | |
+ { | |
+ for (loc.i=1; loc.i lte ListLen(loc.stringCols); loc.i++) | |
+ { | |
+ loc.columnName = ListGetAt(loc.stringCols, loc.i); | |
+ QuerySetCell(arguments.qry, loc.columnName, XMLFormat(arguments.qry[loc.columnName][loc.row]), loc.row); | |
+ } | |
+ } | |
+ </cfscript> | |
+ <cfreturn arguments.qry> | |
+</cffunction> | |
+ | |
+<cffunction name="$getStringColumnsListFromQuery" returntype="string" access="public" output="false"> | |
+ <cfargument name="qry" type="query" required="true"> | |
+ <cfscript> | |
+ var loc = {}; | |
+ loc.returnValue = ""; | |
+ loc.arrMetaData = GetMetaData(arguments.qry); | |
+ for (loc.i=1; loc.i lte ArrayLen(loc.arrMetaData); loc.i++) | |
+ { | |
+ if (ListFindNoCase("char,nchar,varchar,nvarchar,text,ntext", loc.arrMetaData[loc.i].typeName)) | |
+ loc.returnValue = ListAppend(loc.returnValue, loc.arrMetaData[loc.i].name); | |
+ } | |
+ </cfscript> | |
+ <cfreturn loc.returnValue> | |
+</cffunction> | |
\ No newline at end of file | |
diff --git a/wheels/tests/_assets/views/test/_xssAttack.cfm b/wheels/tests/_assets/views/test/_xssAttack.cfm | |
new file mode 100644 | |
index 0000000..15bee3c | |
--- /dev/null | |
+++ b/wheels/tests/_assets/views/test/_xssAttack.cfm | |
@@ -0,0 +1 @@ | |
+<cfoutput>#params.xss#</cfoutput> | |
\ No newline at end of file | |
diff --git a/wheels/tests/global/sanitize/rendering.cfc b/wheels/tests/global/sanitize/rendering.cfc | |
new file mode 100644 | |
index 0000000..fed90b9 | |
--- /dev/null | |
+++ b/wheels/tests/global/sanitize/rendering.cfc | |
@@ -0,0 +1,21 @@ | |
+<cfcomponent extends="wheelsMapping.test"> | |
+ | |
+ <cffunction name="setup"> | |
+ <cfset $$oldViewPath = application.wheels.viewPath> | |
+ <cfset application.wheels.viewPath = "wheels/tests/_assets/views"> | |
+ <cfset xss = '<script>alert("here");</script>'> | |
+ </cffunction> | |
+ | |
+ <cffunction name="teardown"> | |
+ <cfset application.wheels.viewPath = $$oldViewPath> | |
+ </cffunction> | |
+ | |
+ <cffunction name="test_rendering_partial"> | |
+ <cfset params = {controller="test", action="test", xss=xss}> | |
+ <cfset loc.controller = controller(name="test").new(params)> | |
+ <cfset result = loc.controller.renderPartial(partial="xssAttack")> | |
+ <cfset loc.e = XMLFormat(xss)> | |
+ <cfset assert("loc.controller.response() eq loc.e")> ---> | |
+ </cffunction> | |
+ | |
+</cfcomponent> | |
\ No newline at end of file | |
diff --git a/wheels/tests/global/sanitize/values.cfc b/wheels/tests/global/sanitize/values.cfc | |
new file mode 100644 | |
index 0000000..ad0f824 | |
--- /dev/null | |
+++ b/wheels/tests/global/sanitize/values.cfc | |
@@ -0,0 +1,34 @@ | |
+<cfcomponent extends="wheelsMapping.Test"> | |
+ | |
+ <cffunction name="test_nested_params"> | |
+ <cfset loc.a = {}> | |
+ <cfset loc.a.params = { | |
+ author = { | |
+ firstName="tony", | |
+ lastName="o'connor", | |
+ profile = { | |
+ dateOfBirth="10/02/1970 18:01:00", | |
+ bio="<script>alert(""here"");</script>" | |
+ } | |
+ } | |
+ } | |
+ > | |
+ <cfset loc.a = sanitize(loc.a)> | |
+ <cfset assert('loc.a.params.author.firstname eq "tony"')> | |
+ <cfset assert('loc.a.params.author.lastname eq XMLFormat("o''connor")')> | |
+ <cfset assert('loc.a.params.author.profile.bio eq XMLFormat("<script>alert(""here"");</script>")')> | |
+ </cffunction> | |
+ | |
+ <cffunction name="test_query"> | |
+ <cfset loc.a = QueryNew("firstname,lastname,bio")> | |
+ <cfset QueryAddRow(loc.a)> | |
+ <cfset QuerySetCell(loc.a, "firstname", "tony")> | |
+ <cfset QuerySetCell(loc.a, "lastname", "o'connor")> | |
+ <cfset QuerySetCell(loc.a, "bio", "<script>alert(""here"");</script>")> | |
+ <cfset loc.a = sanitize(loc.a)> | |
+ <cfset assert('loc.a.firstname[1] eq "tony"')> | |
+ <cfset assert('loc.a.lastname[1] eq XMLFormat("o''connor")')> | |
+ <cfset assert('loc.a.bio[1] eq XMLFormat("<script>alert(""here"");</script>")')> | |
+ </cffunction> | |
+ | |
+</cfcomponent> | |
\ No newline at end of file | |
-- | |
1.6.1.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment