Portcullis

Portcullis
Download: portcullis-2.0.1.zip
Version: 2.0.1
Author: John Mason (blog: www.codfusion.com)

Release Date: 4/23/2008
Last Update: 1/16/2010
License: Apache License, Version 2

Portcullis is a CFC based url,form,cookie filter to help protect against SQL Injection and XSS scripting attacks. This CFC can help filter input, strip tags and escape HTML based on internal settings. It can also log attacks and temporarily block future attempts based on a set time limit.

This project has been inspired by Shawn Gorrel's popular cf_xssblock tag http://www.illumineti.com/documents/xssblock.txt.
  
WARNING: URL, SQL Injection and XSS attacks are ever evolving threats. Though this CFC will filter many types of attacks. There are no warranties, expressed or implied, with using this filter. It is YOUR responsibility to monitor/modify/update/alter this code to properly protect your application now and in the future. It is also highly encourage to implement a hardware Web Application Firewall (WAF) to obtain the best protection. In fact in many cases, PCI-DSS standards will require WAF when handling credit card information.

1.0.2 (4/23/2008) - First public release
1.0.3 (5/10/2008) - Added CRLF defense, HttpOnly for cookies, function to remove individual IPs from the log and a new escapeChars function that replaces the htmlEditFormat()
1.0.4 (6/19/2008) - Fixed item naming with a regex scan that allows only alphanumeric and underscore characters 
1.0.5 (7/21/2008) - Added some key words to block the popular CAST()/ASCII injection attack. Also, fixed a bug reported if ampersands are in the url string it sometimes mixes up the variable naming
1.0.6 (8/26/2008) - Exception field corrections, fixed a couple missing var scopes, querynew bug in CF6, bug fix for checkReferer
1.0.7 (6/10/2009) - Added to sql and word filters, modified MSWord smart quotes filter
2.0.0 (1/4/2010) - Additions to the keyword list, accessors, context aware sql command words search
2.0.1 (1/16/2010) - New isDetected() method and verification of valid variable names in accordance with the cf variable naming rules

How to use Portcullis

There are a number of settings in the CFC itself. Located at the top in the pseudo constructor area. These settings have notes which explain their purpose.

Typically in your application.cfm or application.cfc page, you can load Portcullis into a shared scope as a singleton.

<cfif isdefined("application.Portcullis") eq false>
   <cfset application.Portcullis = createObject("component","com.fusionlink.Portcullis").init()/>
</cfif>

You can also configure Portcullis through the init method. Look at the last section of this howto.

Now, we can scan scope variables coming into the application..

<cfset application.Portcullis.scan(url,"url",cgi.remote_addr)>
<cfset application.Portcullis.scan(form,"form",cgi.remote_addr)>
<cfset application.Portcullis.scan(cookie,"cookie",cgi.remote_addr)>

If we have blocking on, then we can call Portcullis to determine if a request should be blocked..

<cfif application.Portcullis.isBlocked(cgi.remote_addr) eq true>
   Sorry, there was an error detected.
   <cfmail from="youremail@yourdomain.com"
      to="youremail@yourdomain.com"
      subject="Portcullis: User Blocked" type="html">
      <cfdump var="#cgi#"/>
   </cfmail>
   <cfabort/>
</cfif>

You can also detect on-the-fly if Portcullis caught an attack with the current request via the isDetected() function..

<cfdump var="#application.Portcullis.isDetected()#"/>

If you need to read the list of IP's that are blocked are have tried to do attacks..

<cfdump var="#application.Portcullis.getLog()#"/>

You can remove an IP from the blocked log..

<cfset application.Portcullis.removeIPfromLog(theIPaddress)/>

You can configure Portcullis via its accessors functions (either init or setSettings).

For example..

<cfset settings = StructNew()/>
<cfset settings.log = true/>
<cfset settings.ipBlock = true/>
<cfset application.Portcullis = createObject("component","com.fusionlink.Portcullis").init(settings)/>

This will override the default settings within the component and allow you to dynamically use Portcullis in different modes as needed.
Just refer to the top of the cfc to see the various default settings and their naming.

You can view current Portcullis settings with the getSettings() function..

    <cfdump var="#application.Portcullis.getSettings()#"/>