http://qs321.pair.com?node_id=13136
Category: file convertor
Author/Contact Info BigJoe email: big_joe1008@linuxstart.com
Description: This is a script that I put together for use on my source code page. This script then allows me to copy html and scripts into a dir and let people pick the ones they want to view and I don't have to set up a page for each. It does require a param sent to it by using ?html=filename.
Update 6/2/200 With the help of Fastolfe I have added some testing on the $in{html} to make sure it is not tainted.
#!/usr/bin/perl -w

require "../../cgi-lib.pl";

ReadParse(*in);

$openbr="<";
$closebr="&rt;";
# $listing=`./allhtml.pl`;  #this script outputs a list of all my html
              #files.
if($in{html){
if ($in{html} =~ /^([-\@\w.]+)$/) {
        $filename = $1;                
} else {
        die "Bad data in $in{html}";         
}    

open(LINKPAGE, $filename);
    $filesize = -s LINKPAGE;
    read(LINKPAGE, $wholepage, $filesize);

$wholepage=~s/</$openbr/g;
$wholepage=~s/>/$closebr/g;

print "Content-type: text/html\n\n";
print "<HTML><BODY><PRE>";
print "<FONT size = 5><Center>";
print $in{html};
print  "</Center></FONT><BR>";
print "$wholepage <BR><BR>";
}
print $listing;
print "<!--Written by Joseph Harnish--><A
HREF=\"http://www.csis.gvsu.edu/~harnisjl\">Big Joe
</A></PRE><BR><BR><BR>\n\n
<FORM NAME=\"myForm\" ACTION=\"html2code.pl\" METHOD=\"POST\">
<TABLE CELLPADDING=2 CELLSPACING=0>
<TR><TD WIDTH=50>File name:</TD><TD><INPUT TYPE=TEXT NAME=\"html\"
SIZE=\"30\"></TD></TR>
</TD>
<TR><TD COLSPAN=2><INPUT TYPE=SUBMIT VALUE=\"View\"></TD></TR>
</TABLE>
</FORM>
</BODY></HTML>";

close(LINKPAGE);

exit;
Replies are listed 'Best First'.
DANGER - MAJOR SECURITY ISSUES
by Fastolfe (Vicar) on Jun 03, 2000 at 01:31 UTC
    Please read the 'perlsec' man page.

    open(LINKPAGE, $in{html}); This is one of the worst things you can do in a CGI script. I can pass an argument of html=id;cat+/etc/passwd| to your script, or even more evilly, html=rm+-rf+/| or html=>/etc/passwd or all sorts of evil things.

    You should a) strip out any strange characters; b) verify that the item in $in{html} refers to a filename in an appropriate location; and c) open it with something like open(LINKPAGE, "< $in{html}");

    When writing CGI scripts, always keep perlsec in mind and always run with 'taint checking' enabled (-T). This would have spotted the fact that $in{html} is not safe to trust in critical calls like open() or system().

RE: Code Viewer
by KM (Priest) on Jun 03, 2000 at 04:38 UTC
    I won't tear the code apart, but I highly suggest you do NOT use cgi-lib.pl, but use CGI.pm instead. It does have a 'mode' where you can still use the methods from cgi-lib.pl.

    Also, there is a security concern here, as mentioned in another reply. Please take a look at perlsec, use -T (ALL CGI should use -T), and the Untaint.pm module on CPAN.

    Cheers,
    KM

SERIOUS SECURITY HOLES ABOVE
by merlyn (Sage) on Jun 19, 2000 at 21:46 UTC
    $filename is being reduced without using File::Basename. In this case, the name could contain \n, so the replacement would stop too early, allowing us to have a name with slashes in it. In fact, I think a name of
    "\n|/your/command/here foo bar.gif"
    or whatever $theext is set to would be opened just fine. Actually, I can see that there'd be a little work to get through the maze, but nonetheless, the wrong cargo-cult code was used here, and that makes this code dangerous.

    Also, the Location: header needs a space after the colon, required by RFC.

    As a style issue, using File::Copy would be preferred.

    -- Randal L. Schwartz, Perl hacker

RE: Code Viewer
by BBQ (Curate) on May 25, 2000 at 06:58 UTC
    Humm... I didn't get part of the code. If you have:
    $openbr="<"; $closebr=">";
    and
    $wholepage=~s/</$openbr/g; $wholepage=~s/>/$closebr/g;
    aren't you just saying
    $wholepage=~s/</</g; $wholepage=~s/>/>/g;
    What good does that do?
    I may be missing something here.

    #!/home/bbq/bin/perl
    # Trust no1!
      actually what it was supposed to be instead of
      $openbr="&lt;"; $closebr="&rt;";

      but I think something happened.