LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-06-2003, 08:18 PM   #1
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Rep: Reputation: 46
Perl cgi suggestions?


Code:
#!/usr/local/safe/bin/perl -wT

# use she-bang /usr/local/safe/bin/perl -wT for  host company
# use she-bang /usr/bin/perl -wT for local testing
# use she-bang d:/perl/bin/perl -wT for local testing in windows

# Author: megaspaz
# Date: January 31, 2003
# Last Modified: November 6, 2003
# File: get_image.cgi
# Description:
#	This cgi-script will processes parameters sent to it
#	and fetch the right image specified in parameters if
#	the image exists and generate the following xhtml code.
#	if the image doesn't exist, nothing is done as the default
#	browser behavior is used.
#	This script is copyrighted on January 31, 2001 by J & J Graphics

use strict;
use CGI ':standard';

my $img_rsc=param('image');
my $alt_txt=param('alt1');
print header;
print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<title>J &amp; J Graphics - Illustrations/Layouts</title>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />
<meta name=\"Description\" content=\"Illustrations/Layouts by J &amp; J Graphics\" />
<meta name=\"Keywords\" content=\"Web Design, Graphic Design, Web Design Company, Graphic Design Company, Graphics, Art, Animation, Graphic, Design, Designs, Web, Flash Animation, Flash, Animation\" />
<link href=\"../Styles/style_txt01.css\" rel=\"stylesheet\" type=\"text/css\" />
<script type=\"text/JavaScript\" src=\"../Scripts/jscript.js\"></script>
</head>

<body class=\"bd\">
<div align=\"center\"><em class=\"dv\">This is new window. To return to the website, close this window.</em><br /> 
  <hr />
  <p><img src=\"../images/sm_logo.gif\" alt=\"J &amp; J Graphics Logo\" width=\"90\" height=\"156\" /></p>";

if (!param('alt1'))
{
  $alt_txt="";
}

if (!param('image'))
{
  print "<br /><br />";
  print h1 ("405 Error - Method Not Allowed");
  print h4 ("Undefined Parameter");
}
else
{
  if (!open (FILE, $img_rsc))
  {
    print "<br /><br />";
    print h1 ("404 Error - File Not Found");
    print h4 ("No Such File - \"$img_rsc\"");
  }
  else
  {
    close (FILE);
    print "<p><img src=\"$img_rsc\" width=\"612\" height=\"792\" alt=\"$alt_txt\" /></p>";
  }
}

print "</div>
</body>
</html>";


this is basically a simple cgi that gets images from links on my webpage. it uses a simple post where the parameters are in the url. i don't have any great perl experience, so i have a couple of questions that hopefully some of you can answer.

1. Is this code safe? as in exploitable or prone to Ddos attacks?
2. Do any of you have any suggestions to make it better? as in more robust, etc...

basically the xhtml generation is done manually because i know this validates to xhtml transitional on w3.org. i'm not sure if using the basic cgi perl functions would generate xhtml transitional compliant code.

but anyway, thanks for your consideration in this.

Last edited by megaspaz; 11-06-2003 at 08:19 PM.
 
Old 11-07-2003, 12:51 AM   #2
xode
Member
 
Registered: Aug 2003
Distribution: Mandrake 9.0; FC4; FC8; SUSE 10.3; SUSE 12.1; SUSE 13.2
Posts: 626
Blog Entries: 1

Rep: Reputation: 49
$img_rsc is taken directly from user input and used as a filename to open a file. That is a security hole. You might want to check out this page for details.
 
Old 11-07-2003, 01:18 AM   #3
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Original Poster
Rep: Reputation: 46
Quote:
Originally posted by xode
$img_rsc is taken directly from user input and used as a filename to open a file. That is a security hole. You might want to check out this page for details.
thanks. can you please elaborate a bit? i've got the taint flag set. would you suggest doing something like making value of image that is being passed more generic? like instead of using the path for image maybe make the passed value be descriptive like "picnic" and do case checking that if the value is "picnic" fetch "../images/co_outing.jpg"? thanks again for the link and the suggestion.
 
Old 11-07-2003, 10:55 PM   #4
xode
Member
 
Registered: Aug 2003
Distribution: Mandrake 9.0; FC4; FC8; SUSE 10.3; SUSE 12.1; SUSE 13.2
Posts: 626
Blog Entries: 1

Rep: Reputation: 49
What I typically like to do is force the user to input only alphanumeric characters for the filename, as for example in:

if ($img_rsc =~ /^(\w+)$/) { $img_rsc = $1; } else
{ print...
# show error
}

Assigning $img_rsc to $1 untaints that variable (PERL assumes that you know what you are doing when you build the expression and make the assignment) so you don't get a taint abort when you try to use $img_rsc to open a file.

Then, I also confine all operations to a working subdirectory specifically set up for the script's data. Finally, I set the script's permissions to 711, so the only thing the user can do is run my script without being able to read it, and I set the working subdirectory's permissions to 700 so only the script can see it.

Beyond all this, there is the problem of an experienced hacker using the link mechanism to get into system configuration files and such, which is normally taken care of by Linux user permissions (i.e. the only additional permission that the script has that the user doesn't is the ability to change the contents of its working subdirectory). Details of the link hacking are in the document that I referred you to.
 
Old 11-08-2003, 02:59 AM   #5
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Original Poster
Rep: Reputation: 46
okay i changed that part of the code to this:
Code:
if (!param('image'))
{
  print "<br /><br />";
  print h1 ("405 Error - Method Not Allowed");
  print h4 ("Undefined Or Invalid Parameter");
}
else
{
  if ($img_rsc =~ /^(.*\/?\w+)+$/)
  {
    if (!open (FILE, "< $img_rsc"))
    {
      print "<br /><br />";
      print h1 ("404 Error - File Not Found");
      print h4 ("No Such File - \"$img_rsc\"");
    }
    else
    {
      close (FILE);
      print "<p><img src=\"$img_rsc\" width=\"612\" height=\"792\" alt=\"$alt_txt\" /></p>";
    }
  }
  else
  {
    print "<br /><br />";
    print h1 ("405 Error - Method Not Allowed");
    print h4 ("Undefined Or Invalid Parameter");
  }
}


i'm still not sure exactly what constitutes taintedness. i've read the link you've provided more than a few times, but am still not understanding from their examples why certain scalars are tainted and from your example how assigning a scalar to $1 untaints a scalar. also not sure what $1 even is. or $2, $3, etc... are.

but anyway, this script isn't supposed to take user input. it's just to get a full sized image from a thumbnail image link. user's aren't supposed to manually put in values, even though i am trying to check for that somewhat. i added a regular expression to make sure if the user does try to manually put in something that it least would follow a directory/filename format and if it doesn't, the script generates an error page of invalid method (basically strings of just ^.*$ ). also from the example in the link you provided, it seems to say that opening a file using a tainted scalar value is okay as long as you're opening it as read-only. which is what i did there.

Quote:
open(FOO, "< $arg"); # OK - read-only file
open(FOO, "> $arg"); # Not OK - trying to write
anyway, thanks for you help in all of this again and i hope you can kinda breakdown these new questions i have and comment on the new code in order to tell me if what i think i understand now is either correct or just plain glitched.

Last edited by megaspaz; 11-08-2003 at 03:00 AM.
 
Old 11-09-2003, 09:44 PM   #6
xode
Member
 
Registered: Aug 2003
Distribution: Mandrake 9.0; FC4; FC8; SUSE 10.3; SUSE 12.1; SUSE 13.2
Posts: 626
Blog Entries: 1

Rep: Reputation: 49
Quote:
i'm still not sure exactly what constitutes taintedness.
Any variable that contains, in whole or in part, or, that derives in any manner from, in whole or in part, from any input that the user enters is tainted.

Quote:
also from the example in the link you provided, it seems to say that opening a file using a tainted scalar value is okay as long as you're opening it as read-only. which is what i did there.
I wouldn't use tainted data for anything other than to store it into a database (or compare it to some database contents) under my total control (i.e. my script provides the filename(s) on its own and the user's data simply goes into the file(s) where my script decides to put it) or to print it back to the user.

Quote:
also not sure what $1 even is. or $2, $3, etc... are.
Simple character string: a sequence of characters, none of which perform any special function, or, if the character in question would perform a special function, the function is disabled when the character is put in the string.

Regular expression: a sequence of characters, including characters that perform special functions, such that the regular expression matches zero or more simple character strings.

Sub-expression: a subset of a regular expression that could be a regular expression in itself and that is clearly delineated in the regular expression by being enclosed in ()s when put in the regular expression.

When you do a pattern match in PERL and the match succeeds (i.e. the simple character string contained in the PERL variable matches the regular expression that the variable was compared against), $1 references the left set or the outermost set of ()s in the regular expression itself (i.e. typically, the entire PERL variable that was matched to the regular expression), and $2 through $N reference whatever subexpressions the regular expression had, if any (i.e. various subsets of the PERL variable that was matched). Warning!: don't try to reference beyond however many subexpressions a regular expression has. For example, if a regular expression has 2 subexpressions, don't try to reference $3 or further.

EXAMPLE:

$begin = "begin"; $middle = "middle"; $end = "end";
$inputcheck = ($input =~ /^($begin(.*)$middle(.*)$end)$/is);

# $1 --> ($begin(.*)$middle(.*)$end)
# $2 --> (.*) between $begin and $middle
# $3 --> (.*) between $middle and $end
 
Old 11-09-2003, 10:54 PM   #7
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Original Poster
Rep: Reputation: 46
okay. so then for this code here:

Code:
if ($img_rsc =~ /^(.*\/?\w+)+$/)
if there's a match, then $1 is assigned (.*\/?\w+), or basically what was inputed. and thus, if the user does manually fill in values in the address bar and there's a good match, then $1 is assigned the value of what the user entered. then assigning the original scalar with $1 (which i guess both holds the same values) will untaint the original scalar (this case $img_rsc) ? i take it you could just go and use $1 instead of reassigning the value of $img_rsc with the value of $1.

thanks for the great explaination of all this.
 
Old 11-10-2003, 03:57 PM   #8
xode
Member
 
Registered: Aug 2003
Distribution: Mandrake 9.0; FC4; FC8; SUSE 10.3; SUSE 12.1; SUSE 13.2
Posts: 626
Blog Entries: 1

Rep: Reputation: 49
Quote:
i take it you could just go and use $1 instead of reassigning the value of $img_rsc with the value of $1.
Actually, you do want to reassign $imc_rsc (or whatever other variable you have set up for your use there) to the value of $1, and immediately after the operation, that set the value of $1, is complete. The reason for that is $1 is a very temporary variable and it will have its current value trashed just as soon as you do another pattern match, whereas your own personal variable is more permanent and changes only when you explicitly reference it. I'm sure that you are familiar with Murphy's Law as it applies in these types of situations.

Everything else stated is correct, but there is a caveat. You want to use a very strict and demanding regular expression to do your pattern match against since PERL lets you take the lead and turns over all of the security controls to your regular expression (i.e. $1 being marked as untainted).

($img_rsc =~ /^(.*\/?\w+)+$/) is not a good pattern match to use. In particular, .* will let anything through. You don't want that. In general, you want the user to only be able to enter alphanumeric strings which you then use as all or part of a filename. Your script then supplies the entire path (to the script's working directory that I referenced earlier).

Quote:
thanks for the great explaination of all this.
You're welcome.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl CGI:Can't locate CGI.pm supermyself Programming 13 09-10-2007 06:22 AM
Suggestions for PHP or cgi-based site stats software infidel Linux - Software 5 05-12-2005 11:44 PM
perl cgi neil Programming 3 07-07-2004 04:52 AM
cgi perl : I cant get perl to append my html file... the_y_man Programming 3 03-22-2004 05:07 AM
cgi+perl barbanero General 0 04-07-2002 12:48 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration