homepage Welcome to WebmasterWorld Guest from
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

Web Security

5+ Year Member

Msg#: 4356532 posted 3:47 am on Aug 30, 2011 (gmt 0)

I have some questions concerning the use of security measures in a CGI script. I've been researching this one quite extensively.
One thing I see much of is restricting what kind of characters can be entered into a form field and I've also seen the reasons why. I was wondering if maybe using a regex to replace meta chars would be okay, i.e., $name =~ s/</&#60;/; and make a list of regex replacements for all of the punctuation & meta chars? I realize this would slow things down a slight and be alot of replacement codes to search but the user could still use all characters at will. If this is not a good idea whay should be allowed? Users need to be able to use question marks, periods and a few other punctuation chars. All info is sent directly to a MySql db and column names have been set different than form field names. I am going to research security issues for mysql. Another thing that crossed my mind was, since the forms will probably be run from the application (displays things in the same manner as a guestbook) was upon arrival at the url write a cookie and in the cookie have a password which is created on the fly which must validate against a variable in the processing end of the script seeing how HTTP_REFERER seems to be so undependable. Leave the cookie with no expiration date so it is a fresh code each time the form opens.--just a thought as the password would be different in every case. Maybe I'm just nervous about going live with the script.



WebmasterWorld Senior Member 5+ Year Member

Msg#: 4356532 posted 4:17 am on Aug 30, 2011 (gmt 0)

Generally you need to avoid two attacks: sql injection and html injection.
sql injection is basically the idea, that somebody highjacks your database query, which can happen if you don't escape special characters, mostly the ' which is used to encapsulate strings in mysql. to make sure that's taken care of, use placeholders:

my $sth_insert = $dbh->prepare("INSERT INTO my_table (field1, field2) VALUES (?, ?)");
$sth_insert->execute( $value_for_field1, $value_for_field2 );

and DBI will take care of it for you.

html / code injection should, imho not be defended against by deleting or replacing certain characters in the messages before you enter them into the database, but rather to replace them when you output them. I'd use HTML::Entities. Also, most templating systems have an easy way to escape that.

Setting a Cookie will not defend you against a malicious person that is acting out the attacks himself, but it will help protect against form attacks on your users, where people unknowingly submit a form on your website. there are other measures as well -- how far you go really depends on how much trouble you expect and how many people you think are out to hurt you / your users ;)


5+ Year Member

Msg#: 4356532 posted 5:06 am on Aug 30, 2011 (gmt 0)

Thanks a million. I like the HTML::Entities and the way it removes things. Only thing is I'll need to be able to allow things like question marks and a few other things which is why I was considering the replacement regex's.

Also, the placeholders for entering into mysql is great---I've spent time searching for an error that was a missing 'for a value.

I was always going with
$sth_insert = $dbh->prepare("INSERT INTO my_table (field1, field2) VALUES ('?', '?')");

and had to put all those little single quote marks in.

HTML::TEMPLATE is a definite on the todo list(like next on the list). I really value the recommendations I get from you and have never been steered wrong here.

As far as what I was saying about the cookie with a password the order of operations is as follows:
&password;#sub that writes the passwords
$pword=&password;#just a variable holding &password output

#form in same script that does processing so easy to put the value in the script
&writecookie;#sub that writes cookie--no exp date...cookie value is $pword
&getcookievalue;#cookie value named cookieword
if($cookieword ne $pword){print"Error 403...You don't have permission blah blah";exit(0);}#draw up a 403 type response

This all relies on tha fact that the variable holding $pword is in the script and hacker/cracker not knowing what it is but is mainly to prevent the form not being submitted from the site. The password changes each time the form is opened. Just a thought for later "rainy days"

Thanks again


WebmasterWorld Senior Member 5+ Year Member

Msg#: 4356532 posted 3:49 pm on Aug 30, 2011 (gmt 0)

Yeah, I understand the rationale behind the cookies, and it will most likely protect you / your users from the form not being submitted from your site. On the other hand: checking the referer will do that aswell. Yes, the referer can easily be faked by a malicious user, but you can't just put a form on a website that automatically fakes the referer when it is submitted.
While the user himself (if he is experienced enough) can fake the referer: he could just as easily build a bot that visits the form-page on your website, gets the cookie and then sends a request to the script that processes the form and send the correct cookie with it.

Btw: I did not mean to recommend HTML::Template. I've used it, and I think the Template Toolkit is much better, so if you're not decided yet and haven't invested time into learning any template language / syntax, I recommend TT. You should probably open a thread for that and ask for more opinions when you're ready to dive in.


5+ Year Member

Msg#: 4356532 posted 11:50 pm on Aug 30, 2011 (gmt 0)

I'm sure you have already seen this one, but, for the bots....I've put a field in a form and gave it a common name like name and using css made it invisible, that is, i.e., .inv{display:none;} and in the form used that to hide the input(using a regular text input). When it gets to the form processing if just have a statement like:
if($name ne ""){&thanx;} with the thanx page being the one that says "We have recieved your information, yak blah blah.


5+ Year Member

Msg#: 4356532 posted 5:54 am on Sep 4, 2011 (gmt 0)

I have a question regarding the HTML::Entities pm. At cpan in the synopsis for the module it says:

use HTML::Entities ();
my $decoded = HTML::Entities::decode($a);
my $encoded = HTML::Entities::encode($a);
my $encoded = HTML::Entities::encode_numeric($a);

I tried some different things but always getting the same results. Using this module shouldn't the html source code read the &#36; instead of displaying a $ sign after the form is submitted. I like the idea but just not sure how to use it. I tried replacing the $a with the form field variables---placing them in the arguements () spot after use HTML::Entities drew an error with the -T switch. I've been trying to find information which explains using "layman's term" on how to use the module. Is there something I'm supposed to config in the code I listed above?


WebmasterWorld Administrator phranque us a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

Msg#: 4356532 posted 8:28 am on Sep 4, 2011 (gmt 0)

http://search.cpan.org/~gaas/HTML-Parser/lib/HTML/Entities.pm#DESCRIPTION [search.cpan.org]:
The default set of characters to encode are control chars, high-bit chars, and the <, &, >, ' and " characters.

"$a" should be the text string you want encoded.

use HTML::Entities ();
my $encoded = HTML::Entities::encode($a);

should encode the above listed characters in $a and the encoded string is in $encoded


5+ Year Member

Msg#: 4356532 posted 1:02 pm on Sep 4, 2011 (gmt 0)

I understand it now. Only problem is it still allows metacharacters like a backtick to go through. Wouldn't a substitution regex be better? If substituted anything could still be used. What characters shouldn't be allowed to pass through a form? I mean there are only so many that can be damaging, right?


5+ Year Member

Msg#: 4356532 posted 2:39 pm on Sep 4, 2011 (gmt 0)

I apologize if I'm sounding dumb about this thing with the meta chars. Perhaps I'm just not understanding the capabilities of the HTML::Entities pm. I was just reading something about it and it more or less mentions that it decodes the meta characters more or less rendering their power useless. I'm really curious about the effectiveness because I see so many things like forums where metacharacters enter through user input. If that is true that is great and don't need it explained as I probably would not understand it anyway but will be just happy knowing it does what I mentioned.


WebmasterWorld Senior Member 10+ Year Member

Msg#: 4356532 posted 4:42 pm on Sep 4, 2011 (gmt 0)

Hi typomania. Perl has some cool tricks that you might find useful.

Use the tr operator to strip out unwelcome characters from the submitted form data. Example:

my $e = 'abcd!@#$%^&*()_{}[]:<>?,.efg1234';
# allow only alphanumerical characters and some basic punctuation
$e =~ tr/a-zA-Z0-9?!,.//cd;

outputs: abcd!?,.efg1234

Another trick I find useful is to encode meta-characters to hex when I need to save them safely. You can worry about making the characters safe when you are ready to use them.

my $e = 'abcd!@#$%^&*()_{}[]:<>?,.efg1234';
# convert non alphanumericals characters to hex (ie: ! character converts to %21)
$e =~ s/([^0-9A-Za-z])/sprintf("%%%02X", ord($1))/seg;
# convert string to html hex entity
$e =~ s/%([A-Fa-f0-9]{2})/&#x$1;/g;

outputs: abcd&#x21;&#x40;&#x23;&#x24;&#x25;&#x5E;&#x26;&#x2A;&#x28;&#x29;&#x5F;&#x7B;

The last two lines of code is intended for demonstration purposes for western browsers as the html hex output may not be internationally supported.


WebmasterWorld Senior Member 5+ Year Member

Msg#: 4356532 posted 6:50 pm on Sep 4, 2011 (gmt 0)

I understand it now. Only problem is it still allows metacharacters like a backtick to go through. [...] I mean there are only so many that can be damaging, right?

meta characters depend on where you work with a string. ' and ` might be meta characters for mysql, but they are not for html. HTML::Entities only escapes those entities that need escaping for HTML-Output. If you want to specify which characters it should escape, you can:
$encoded = encode_entities($input, '<>&"');

Where the second parameter is a string with the chars to escape. You could also supply a regexp:

# and this would only encode non-plain ascii:
$encoded = encode_entities($input, '^\n\x20-\x25\x27-\x7e');

Both examples are from the modules documentation at cpan [search.cpan.org]

If you output (x)HTML, HTML::Entities will make your output safe. Nobody can smuggle in XSS-Attacks by entering javascript-code etc pp.
That's the output-part. The input-part is what you're doing with the placeholders in SQL.
If you don't execute any programs based on user input, you are safe with that.


5+ Year Member

Msg#: 4356532 posted 11:36 pm on Sep 5, 2011 (gmt 0)

Sounds good to me. You'll never know how much help you've been. The only thing executed is the inserts to MySql after a review type page. Thanx again--for everything.


WebmasterWorld Senior Member 5+ Year Member

Msg#: 4356532 posted 6:04 pm on Sep 6, 2011 (gmt 0)

You're very welcome.
Don't hesitate to ask if you don't feel sure on something.

It seems, perl is either not really used by the folks here on WebmasterWorld or the perl-users are not having any questions and problems.
Anyway: it is way too silent in the perl section, so any new questions are always welcome, and I'm sure I am not the only one who feels that way.


5+ Year Member

Msg#: 4356532 posted 2:06 pm on Sep 9, 2011 (gmt 0)

Well, there is one thing at this time that has my curiosity and that involves encrypting passwords. If passwords are stored in a mysql db should they be encrypted? The files which will be using them are an admin and will be behind an htacess passworded directory.


WebmasterWorld Senior Member 10+ Year Member

Msg#: 4356532 posted 2:35 pm on Sep 9, 2011 (gmt 0)

Passwords and other sensitive information should always be encrypted, regardless of where they are stored.

Global Options:
 top home search open messages active posts  

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved