Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sanitizing user input 1

Status
Not open for further replies.

jesse1

Programmer
Aug 29, 2008
30
US
i want to keep my users from entering harmful html or sql code. I thought of use one of the two solutions. I just want to know If these are efficient answers. The first one would have to be expanded but the concept is there.
Code:
<cfset thecomments = #Replacelist(form.comments, "<, >", "&lt;, &gt;")#>
or
Code:
<cfset thecomments =#REReplaceNoCase (form.comments, '[^a-z0-9]', '', 'all')#>
 
HTMLEditFormat() will preserve the brackets and other characters that could be valid in comments (instead of removing them). Just make sure you handle these on the display end too.

And lets not forget the harmful sql code. in your cfquery use PreserveSingleQuotes()

no need to reinvent the wheel.
 
I checked out cflib.com, recommended by cfsearching and found the follwoing. It protects against HTMl, Scripts and Applets. But will it help against SQL injections?


Description:
Strips out nasty HTML/scripting but leaves friendly HTML formatting in place. This tag is useful for processing the input from form fields where you want to let the end-user put in HTML but want to avoid letting them put in tags that cause weirdness and/or security problems such as the SCRIPT tag or an onClick event.

Return Values:
Returns a string.

Example:

<CFSET STR = "This is text with a <SCRIPT> in it.">
<CFSET STR2 = "Another example w/ <APPLET> bad stuff.">
<CFOUTPUT>
#SafeText(STR)#<BR>
#SafeText(STR,1)#
</CFOUTPUT>

Parameters:

Name Description Required
text String to be modified. Yes
strip Boolean value (defaults to false) that determines if HTML should be stripped or just escaped out. No
badTags A list of bad tags. Has a long default list. Consult source. No
badEvents A list of bad HTML events. Has a long default list. Consult source. No

Full UDF Source:

<cfscript>
/**
* Removes potentially nasty HTML text.
* Version 2 by Lena Aleksandrova - changes include fixing a bug w/ arguments and use of REreplace where REreplaceNoCase should have been used.
* version 4 fix by Javier Julio - when a bad event is removed, remove the arg too, ie, remove onclick=&quot;foo&quot;, not just onclick.
*
* @param text String to be modified. (Required)
* @param strip Boolean value (defaults to false) that determines if HTML should be stripped or just escaped out. (Optional)
* @param badTags A list of bad tags. Has a long default list. Consult source. (Optional)
* @param badEvents A list of bad HTML events. Has a long default list. Consult source. (Optional)
* @return Returns a string.
* @author Nathan Dintenfass (nathan@changemedia.com)
* @version 4, October 16, 2006
*/
function safetext(text) {
//default mode is "escape"
var mode = "escape";
//the things to strip out (badTags are HTML tags to strip and badEvents are intra-tag stuff to kill)
//you can change this list to suit your needs
var badTags = "SCRIPT,OBJECT,APPLET,EMBED,FORM,LAYER,ILAYER,FRAME,IFRAME,FRAMESET,PARAM,META";
var badEvents = "onClick,onDblClick,onKeyDown,onKeyPress,onKeyUp,onMouseDown,onMouseOut,onMouseUp,onMouseOver,onBlur,onChange,onFocus,onSelect,javascript:";
var stripperRE = "";

//set up variable to parse and while we're at it trim white space
var theText = trim(text);
//find the first open bracket to start parsing
var obracket = find("<",theText);
//var for badTag
var badTag = "";
//var for the next start in the parse loop
var nextStart = "";
//if there is more than one argument and the second argument is boolean TRUE, we are stripping
if(arraylen(arguments) GT 1 AND isBoolean(arguments[2]) AND arguments[2]) mode = "strip";
if(arraylen(arguments) GT 2 and len(arguments[3])) badTags = arguments[3];
if(arraylen(arguments) GT 3 and len(arguments[4])) badEvents = arguments[4];
//the regular expression used to stip tags
stripperRE = "</?(" & listChangeDelims(badTags,"|") & ")[^>]*>";
//Deal with "smart quotes" and other "special" chars from MS Word
theText = replaceList(theText,chr(8216) & "," & chr(8217) & "," & chr(8220) & "," & chr(8221) & "," & chr(8212) & "," & chr(8213) & "," & chr(8230),"',',"","",--,--,...");
//if escaping, run through the code bracket by bracket and escape the bad tags.
if(mode is "escape"){
//go until no more open brackets to find
while(obracket){
//find the next instance of one of the bad tags
badTag = REFindNoCase(stripperRE,theText,obracket,1);
//if a bad tag is found, escape it
if(badTag.pos[1]){
theText = replace(theText,mid(TheText,badtag.pos[1],badtag.len[1]),HTMLEditFormat(mid(TheText,badtag.pos[1],badtag.len[1])),"ALL");
nextStart = badTag.pos[1] + badTag.len[1];
}
//if no bad tag is found, move on
else{
nextStart = obracket + 1;
}
//find the next open bracket
obracket = find("<",theText,nextStart);
}
}
//if not escaping, assume stripping
else{
theText = REReplaceNoCase(theText,stripperRE,"","ALL");
}
//now kill the bad "events" (intra tag text)
theText = REReplaceNoCase(theText,'(#ListChangeDelims(badEvents,"|")#)[^ >]*',"","ALL");
//return theText
return theText;
}
</cfscript>

 
But will it help against SQL injections?

There are other functions specifically geared towards sql injection. One example is sqlSafe

But you should also check out the complete database library:

That said, you should always use cfqueryparam. The main purpose of cfqueryparam is to provide performance benefits. However, they also have the side benefit of helping protect against common forms of sql injection.

PreserveSingleQuotes on the other hand, is a sure way to expose your database to sql injection. By default, most versions of CF escape trailing single quotes. It is a built in protection against a certain type of sql injection. By using PreserveSingleQuotes you remove that protection and leave your database wide open to attacks.

I would also do a search on ColdFusion + sql injection. There has been a recent rise in ColdFusion specific attacks lately.



----------------------------------
 
Would this be the safest way to solve the problem. Below is the SaveSQL script from CFLIB.com.

<cfset myUsername = sqlSafe(form.username)>

<cfset finalUsername = <cfqueryparam value="#myUsername#" cfsqltype="cf_sql_varchar">



Code:
Example:

<cfset username = sqlSafe(form.username)>

Parameters:

Name Description Required 
string String to modify. Yes 

Full UDF Source:

<cfscript>
/**
* Cleans string of potential sql injection.
* 
* @param string      String to modify. (Required)
* @return Returns a string. 
* @author Bryan Murphy (bryan@guardianlogic.com) 
* @version 1, May 26, 2005 
*/
function metaguardSQLSafe(string) {
var sqlList = "-- ,'";
var replacementList = "#chr(38)##chr(35)##chr(52)##chr(53)##chr(59)##chr(38)##chr(35)##chr(52)##chr(53)##chr(59)# , #chr(38)##chr(35)##chr(51)##chr(57)##chr(59)#";

return trim(replaceList( string , sqlList , replacementList ));
}
</cfscript>

 
That script would help - but - crackers are constantly working up new attack strings and defenders are always a bit behind the curve. You need multiple layers of protection.

If you can limit entry to alphas and numbers only then you are pretty safe.

<cfset thecomments =REReplaceNoCase (form.comments, '[^a-z0-9]', '', 'all')>

When you allow special characters then the risks skyrocket. Don't forget any field is open to attack - hidden form fields, drop lists, password fields (everyone forgets those).

You need to use cfqueryparam, htmledit format, ditto what cfsearching said about PreserveSingleQuotes, and you need to limit special characters unless you have no choice. If you allow special characters then you need to use the bad string removal functions available at cflib. Again just keep in mind those functions get dated and were probably not 100% effective even when first written.

It's a war out there.


 
Is there a way to modify this to also allow only the following wo characters:
"@" and "."

<cfset thecomments =REReplaceNoCase (form.comments, '[^a-z0-9]', '', 'all')>
 
It's a war out there.

They are getting more creative. One of the recent round of attacks just uses hex. With the exception of ")" and ";" the content is not much to raise suspicion. Unless you are checking for known attack strings like EXEC and DECLARE. I know some people take a more aggressive approach and outright reject any requests where a potential attack is detected.


----------------------------------
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top