Remove JavaScript and other unwanted codes from a ColdFusion String

It is quite simple to inject a <script> or a <meta> tags using your form and do something you absolutely don't want to see happening in your webpage. It won't take much, except little bit of luck and a html enabled form, like a FCK Editor enabled form that we all like to use time to time.

Here I assembled a simple function to remove all those codes from a given string, so you can clean your input data, before you send it to the database or save anywhere else.

This function can replace/find any string between <script> </script> tags, even when it is typed with extra spaces. That mean this can work with all of the following scenarios:

   1: <script> </script>
   2: < script> </script> [space in the beginning (browsers normally ignore this
   3: scenario)]
   4: <script> </script > [space at the end of the tag]
   5: <script type="text/javascript"></script>
Show/Hide Line Numbers . Full Screen . Plain

Also with Meta Refresh:
   1: <meta HTTP-EQUIV="REFRESH content="0; url=http://sTo-Undesirable-Location">

Also <link> tag, that you can use to include external JavaScript file or CSS
file.

   1: <link href="http://From-Undesirable-Location/ohMy.js" type="text/javascript">

This will also remove iFrame and Object tags too. and finally JavaScript events

   1: <div onmouseover='window.location = "http://To-Undesirable-Location"'></div>

   1: <cffunction name="cleanup" access="private" returntype="string" output="Yes" hint="Possible Malicious html code from a given string">
   2:  <cfargument name="str"    type="string" required="yes" hint="String">
   3:  <cfargument name="action" type="string" required="no" default="cleanup" hint="If [cleanup], this will clean up the string and output new string, if [find], this will output a value or zero">
   4:  <!--- **************************************************************************** --->
   5:  <!--- Remove string between <script> <object><iframe><style><meta> and <link> tags --->
   6:  <!--- @param str     String to clean up. (Required)                                --->
   7:  <!--- @param action    Replace and Clean up or Find                                --->
   8:  <!--- @author         Saman W Jayasekara (sam @ cflove . org)                     --->
   9:  <!--- @version 1.1    May 22, 2010                                                 --->
  10:  <!--- **************************************************************************** --->
  11:  <cfswitch expression="#arguments.action#">
  12:     <cfcase value="cleanup">
  13:     <cfset local.str = ReReplaceNoCase(arguments.str,"<script.*?</*.script*.>|<applet.*?</*.applet*.>|<embed.*?</*.embed*.>|<ilayer.*?</*.ilayer*.>|<frame.*?</*.frame*.>|<object.*?</*.object*.>|<iframe.*?</*.iframe*.>|<style.*?</*.style*.>|<meta([^>]*[^/])>|<link([^>]*[^/])>|<script([^>]*[^/])>", "", "ALL")>
  14:     <cfset local.str = local.str.ReplaceAll("<\w+[^>]*\son\w+=.*[ /]*>|<script.*/
*>|</*.script>|<[^>]*(javascript:)[^>]*>|<[^>]*(onClick:)[^>]*>|<[^>]*(onDblClick:)[^>]*>|<[^>]*(onMouseDown:)[^>]*>|<[^>]*(onMouseOut:)[^>]*>|<[^>]*(onMouseUp:)[^>]*>|<[^>]*(onMouseOver:)[^>]*>|<[^>]*(onBlur:)[^>]*>|<[^>]*(onFocus:)[^>]*>|<[^>]*(onSelect:)[^>]*>"
,"")
>
  15:     <cfset local.str = reReplaceNoCase(local.str, "</?(script|applet|embed|ilayer|frame|iframe|frameset|style|link)[^>]*>","","all")>
  16:     </cfcase>
  17:     <cfdefaultcase>
  18:     <cfset local.str = REFindNoCase("<script.*?</script*.>|<applet.*?</applet*.>|<embed.*?</embed*.>|<ilayer.*?</ilayer*.>|<frame.*?</frame*.>|<object.*?</object*.>|<iframe.*?</iframe*.>|<style.*?</style*.>|<meta([^>]*[^/])>|<link([^>]*[^/])>|<\w+[^>]*\son\w+=.*[ /]*>|<[^>]*(javascript:)[^>]*>|<[^>]*(onClick:)[^>]*>|<[^>]*(onDblClick:)[^>]*>|<[^>]*(onMouseDown:)[^>]*>|<[^>]*(onMouseOut:)[^>]*>|<[^>]*(onMouseUp:)[^>]*>|<[^>]*(onMouseOver:)[^>]*>|<[^>]*(onBlur:)[^>]*>|<[^>]*(onFocus:)[^>]*>|<[^>]*(onSelect:)[^>]*>",arguments.str)>
  19:     </cfdefaultcase>
  20:  </cfswitch>
  21:  <cfreturn local.str>
  22: </cffunction>
Show/Hide Line Numbers . Full Screen . Plain

6 Comments :
Sunday 26 August 2012 07:28 AM
To identify whether the script has removed some code or not I propose just to teat if strings are identical before versus after replacing.
before line 12: <cfset local.strbackup = local.str>
before line 20: <cfif len(local.strbackup) NEQ len(local.str)><cfmail .......><!-- her goes an alert email ---></cfif>
Sunday 12 August 2012 12:34 PM
Thanks, got it.
Sunday 12 August 2012 10:26 AM
This is great, but my Coldfusion skills are back about CF5, and I'm having trouble implementing the CFC . I want to clean pages where an iframe has been injected. The page is grabbed by CFFile: action="read" variable="tempFile". How do you apply this function to tempFile before overwriting the hacked page?
Sunday 12 August 2012 12:22 PM
You do not have to put all custom functions into a cfc. Just copy the function any where in your page (top, bottom, doesn't matter), and you can use cleanup() within that page.
for example, you can do this <cfset cleanhtml = cleanup(dirtyhtml)>

If you only want to remove iframe, you can edit this function to only take that tag out (line 15).
Doug
Monday 13 August 2012 10:46 AM
I would like to know if the script, which works great BTW, finds anything to clean. That might help us identify the security hole. In my own clunky script I sent myself an email if findnocase returned a positive value. How would you do that in your script? Thanks.

Monday 13 August 2012 10:34 PM
just put that inside an cfif condition in your main page .. like:
<cfif cleanup(dirtyhtml)>
<cfmail>your mail goes here.. </cfmail>
</cfif>