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 Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Security Question

Status
Not open for further replies.

audiopro

Programmer
Joined
Apr 1, 2004
Messages
3,165
Location
GB
I have been reading up on web security and I am getting paranoid.
I operate under taint mode - although I must confess to being a little in the dark as to what that means.
I am using the following code in order to filter input from a form.
Code:
$TEST =~ s/[^a-zA-Z0-9@\/.,: ]//g;

It works as expected but I am trying to make it as secure as possible and found that if a user enters '<SCRIPT>' into a form field it treats it as a Java Code and it is not filtered. I assume that I could follow this with some other code and do some harm. I need to avoid this security hole and obviously I could check for the word '<SCRIPT>' in STDIN.
Is there a better way of doing this and what other holes should I be aware of?

Keith
 
a quick and dirty fix would be to replace the <> with their html entities &lt; and &gt;

Code:
$input=~s/</&lt;/g;
$input=~s/>/&gt;/g;

just a thought, the <SCRIPT> would be rendered on screen, so you'd know someone was up to something



Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Your regex should filter out the "<" and ">" characters so I don't see what your problem is.
Are you sure that you are not trying to use the value before you apply that regex?



Trojan.
 
Thanks Paul - I want to get to the bottom of the problem for my own peace of mind.

Trojan.
I thought the regex would filter it too.
Here is the chopped down code, as always it is only part of a much bigger picture.
Param is loaded into test.
It is a submitted form field, the name of which is stored in a multi dim array.
Example of submitted form field contents
Code:
DICTIONARY <SCRIPT>

Goes through filter but does not filter the arrows.
CSS formatting goes haywire.
Insert the crude check, $TEST is reset and the formatting is fine.
<SCRIPT> is causing the problem at this point.
Another interesting point is that if I allow <SCRIPT> into the table, it messes up the CSS each time it is retrieved and printed on screen.

Code:
my $TEST=$query->param($SOURCE_NAME[$WHICH_TABLE][$x]) || "";
$CHECK1=$TEST;
$TEST =~ s/[^a-zA-Z0-9@\/.,: ]//g;
$CHECK2=$TEST;

# !!!! CRUDE TEST FOR JAVASCRIPT COMPONENT
#if($TEST=~ m/<SCRIPT>/){
#	$TEST="";
#	&WARNING_NOTE("SECURITY ALERT - ILLEGAL CONTENT");
#}

if($CHECK1 ne $CHECK2){
	print "Chrs Removed - $CHECK1 - $CHECK2<br>";
}

Keith
 
first, print $TEST to make sure it is what you think:

Code:
my $TEST=$query->param($SOURCE_NAME[$WHICH_TABLE][$x]) || "";
print "TEST before: $TEST\n";
$CHECK1=$TEST;
$TEST =~ s/[^a-zA-Z0-9@\/.,: ]//g;
print "TEST after: $TEST\n";
$CHECK2=$TEST;

the regexp should be removing <> so I don't see how $TEST could equal <SCRIPT>
 
hi,
only taking care of the <script> tag is only part of the puzzle becase CSS, etc can also be used to run JS on a page. one example on top of my head:
Code:
<div style="background-image:url(jav
asc
ript:window.alert('hi'))">test</div>

plus there is a lot of other sneaky stuff users can submit on a site. My best bet is always using the what is allowed, tags like <b>, <i>, <em>, etc.. so this way you have a much better control.

---
cheers!
san
smoking3vc.gif


print length "The answer to life, universe & everything!
 
True san, but if the tags <> are escaped or removed no html/javascript will work
 
Am I right in thinking this field should be a DB table name?
If so, surely you should look it up from a hash and reject it if it doesn't match.
You could create a hash called, say, "tableNames" an populate it with the table names that are available. Then your code simply needs to say "handleBadTableName($name) unless(exists($tableNames{$name}));"

It would be much simpler and safer that way.



Trojan.
 
You could use HTML::TagFilter to ensure that unwanted HTML isn't submitted. You can allow some tags while disallowing some attributes of those tags (e.g. style, onClick, etc.).
 
I put <SCRIPT> into the field in addition to what is required in form input, as a test and all the formatting went haywire.

Kevin
$TEST is the name of the field as expected.
I agree, the regex should filter out the arrows but it doesn't.
Trojan
As a complication, I will have to allow the arrows as there are a couple of drop down menus in the final script which contain them as acceptable input. I have removed them for now t get to the bottom of the problem.
I will create a simple script tomorrow to test the problem just in case I am missing something.
I will get to the bottom of this if it kills me.


Keith
 
All the more reason to use a hash if at all possible.
It would be really useful if you could explain what content is acceptable and what is not.



Trojan.
 
Keith

If this stuff is being put into a table at some point, you need to make sure you proof it against SQL injections, too. Simplest method is to make sure any SQL queries or updates are strictly controlled by PREPAREing any statements with ? placeholders, and then executing them with the user-supplied data as parameters.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::PerlDesignPatterns)[/small]
 
Thanks Steve
The script contains many queries but there is only 1, well 2, if you count the text or num option where user input is written to the Db.
This handles the output of a number of forms whose field names are loaded from a number of arrays.

Code:
if($results[1] eq "text"){

$sql2="UPDATE $TABLE_NAME[$WHICH_TABLE] SET $SOURCE_NAME[$WHICH_TABLE][$x] = '$SAVE_VALUE[$x]' WHERE NUM=$FILENUM";

}else{

$sql2="UPDATE $TABLE_NAME[$WHICH_TABLE] SET $SOURCE_NAME[$WHICH_TABLE][$x] = $SAVE_VALUE[$x] WHERE NUM=$FILENUM";

}
$sth1=$dbh->prepare($sql2);
$sth1->execute();
$TABLE_NAME[$WHICH_TABLE] - Table name from array
$SAVE_VALUE[$x] can either be a value returned from a function or input from the user via a form.
$FILENUM - file number - never revealed to visitor
Are there any possible security holes in there?


Keith
 
Keith

Suppose I set $x = "='You''ve been tangoed!';" or some similarly crafted text on your form? Every row on your table gets hit, because the ';' terminates the statement before the WHERE clause gets parsed. The PREPARE + ? method only works on the values, not if you are building up the structural part of the statement.

You will have to be especially vigilant when validating the input from the user to make sure it does not include anything that would allow an attacker to hijack your SQL call.

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::PerlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top