<?xml version="1.0" encoding="utf-8" ?>
<!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" lang="en-US" xml:lang="en-US">
<head>
<link rel="shortcut icon" href="/perl/img/rez-favicon.gif" />
<link rel="stylesheet" href="/css/rez2.css" type="text/css" />
<script type="text/javascript" src="/css/noframe.js"></script>
<meta name="robots" content="nocache,noarchive" />
<meta name="keywords" content="resume, ashley evan pond, ashley pond v, perl, programmer, javascript, flash, mod_perl, mod perl, graphics, graphix, web design, webdeveloper, web developer, graphic designer, resume, coder, script, scripter, hacker, available" /> <meta name="description" content="Description Let's create a CGI that views the sources of files. This could be used to look at CGI code or even raw HTML, though your browser..." /> <title>File viewer
</title>
</head>

<body>

<div style="border-bottom:1px solid
#633; margin-bottom: -1px; background-color:#ffb;padding:1ex 1em 1.1ex 1.6em; font-size:10px; line-height:120%">
<abbr title="nota bene">NB</abbr>: These pages were mostly written
in 2001 or so. The résumé dates are accurate but the
code is aged and unlike whiskey, 8 year-old code doesn't usually taste
better. For a look at my current skills and to see my CPAN
modules, sample code, and code discussions, please see these pages
instead: <a href="http://sedition.com/a/972">Perl resources and sample code</a> and <a href="http://pangyresoft.com">PangyreSoft</a>.
</div>

<table class="bodyTable" border="0" cellpadding="0" cellspacing="0"><tr>
  <td class="top" colspan="2">

<div class="title"> File viewer
 </div>

  </td>
  <td class="right" rowspan="2"> <div class="heading">
Social links
</div>

<div style="text-align:center">
<a href="http://www.linkedin.com/in/ashleypondv"><img
src="http://www.linkedin.com/img/webpromo/btn_liprofile_blue_80x15.gif"
style="margin: 10px auto 15px; width:80px;height:15px;border:0" alt="View Ashley Pond V's profile on LinkedIn"/></a>
</div>

<div class="heading">
<a style="color:#000031;" href="/perl/code-index.html">Selected code</a>
</div>

<div class="rightlink">
<a href="/perl/prototype.html">Class::Prototype</a><br />
<a href="/perl/spyder-pod.html">WWW::Spyder</a><br />
<a href="/perl/javascript.html">Javascript tricks</a><br />
<a href="/perl/serial.html">serial() join function</a><br />
<a href="/perl/quotes.html">Smart quotes</a><br />
<a href="/perl/delim-to-excel.html">Text to Excel</a>

<br /><br />

<a href="http://feather.elektrum.org/">Developing Featherweight Web Services with JavaScript</a>

</div>


<div class="heading">
<a style="color:#000031;" href="/perl/design-index.html">Design</a>
</div>

<div class="rightlink">
<a href="icon.html">Web graphics</a><br />
<a href="/perl/typo.html">Typefaces</a><br />
<a href="/perl/lexitypo.html">Typography lexicon</a><br />
<a href="/perl/aux/ad-spread.html">Tower ads</a>

</div>

<div class="heading">
Miscellaneous
</div>
<div class="rightlink">
<a href="reference-index.html">FAQ</a><br />
<a 
href="mailto:perl@sedition.com?subject=What%20is%20wrong%20with%20your%20site?!">Report 
a bug or typo</a><br />
<a href="/perl/perl-jobs.html">Perl job listings</a><br />
<a href="/perl/bib.html">Essential Perl books</a>

</div>

<div class="heading">
<a style="color:#000031;" href="/perl/resume.html">Résumé</a>
</div>
<div class="rightlink">
<a href="resume.html">Résumé</a>

</div>
  <div style="text-align:center;margin:1.3em;padding:2px 3px 2px 3px;background-color:#D5683E">
<script type="text/javascript"><!--
google_ad_client = "pub-3741595817388494";
google_alternate_color = "E38A6C";
google_ad_width = 120;
google_ad_height = 600;
google_ad_format = "120x600_as";
google_ad_channel ="7278227680";
google_color_border = "D5683E";
google_color_bg = "E38A6C";
google_color_link = "001199";
google_color_url = "005588";
google_color_text = "000011";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div> </td>
  </tr><tr>
  <td class="left" rowspan="2">   <div class="leftbar">  <a href="code-index.html ">Code pages</a>  </div>   <div class="leftlink">  <a href="css-outline.html">Cascading outlines with style
</a>  </div>    <div class="leftlink">  <a href="cgi.html">CGI with dispatch hash
</a>  </div>    <div class="leftlink">  <a href="cgi-style.html">CGI with stylesheet
</a>  </div>    <div class="leftlink">  <a href="prototype.html">Class::Prototype, for fast OOP...</a>  </div>      <div class="leftlink">  <a href="perl-colorizer.html">Coloring perl code in...</a>  </div>    <div class="leftlink">  <a href="delim-to-excel.html">Converting delimited text to...</a>  </div>    <div class="leftlink">  <a href="excel-to-delim.html">Converting Excel to delimited...</a>  </div>    <div class="leftlink">  <a href="css-recipes.html">CSS recipes
</a>  </div>    <div class="leftlink">  <a href="perl-shell.html">Fake Perl shell
</a>  </div>    <div class="leftlink">  <div class="leftdead">File viewer
</div>  </div>    <div class="leftlink">  <a href="automata.html">Finite automata in Perl
</a>  </div>    <div class="leftlink">  <a href="rss-feed.html">Installing an RSS feed...</a>  </div>    <div class="leftlink">  <a href="db-converter.html">Moving DB_Files between disparate...</a>  </div>    <div class="leftlink">  <a href="oop.html">Object Oriented colors in...</a>  </div>    <div class="leftlink">  <a href="oop2.html">Object Oriented colors, page...</a>  </div>    <div class="leftlink">  <a href="operator.html">Operator, Operator
</a>  </div>    <div class="leftlink">  <a href="pretty-rows.html">Pretty HTML rows with...</a>  </div>    <div class="leftlink">  <a href="random-quote-cgi.html">Random quote CGI
</a>  </div>    <div class="leftlink">  <a href="javascript-fy.html">Randomize arrays in JavaScript...</a>  </div>    <div class="leftlink">  <a href="mod_perl.html">Redirect with mod_perl
</a>  </div>    <div class="leftlink">  <a href="scramble-meaning.html">Scrambled letters, clear meaning
</a>  </div>    <div class="leftlink">  <a href="serial.html">serial(), serial comma join...</a>  </div>    <div class="leftlink">  <a href="quotes.html">Smart quotes with Perl
</a>  </div>    <div class="leftlink">  <a href="cgi-javascript-spell.html">Spell checking in forms...</a>  </div>    <div class="leftlink">  <a href="javascript.html">Stupid JavaScript Tricks
</a>  </div>    <div class="leftlink">  <a href="dynamically-targeted-amnz-ads.html">Targeting Amazon.com Associate Ad...</a>  </div>    <div class="leftlink">  <a href="variegated.html">Various recipes in Perl...</a>  </div>    <div class="leftlink">  <a href="spyder-pod.html">WWW::Spyder POD
</a>  </div>    <div class="leftlink">  <a href="spyder.html">WWW::Spyder, for simple, easy...</a>  </div>    <div class="leftlink">  <a href="spyder-mini-bio.html">WWW::Spyder, spyder-mini-bio 
</a>  </div>   <br />  <div class="leftbar">
Other pages
</div>          <div class="leftlink">
<a style="font-weight:bold;" href="design-index.html">Design</a>
</div>      <div class="leftlink">
<a style="font-weight:bold;" href="reference-index.html">Reference</a>
</div>      </td>
  <td class="center">   <p class="subtitle"> Description </p>   <p>
  Let’s create a CGI that views the sources of files. This could be used
to look at CGI code or even raw HTML, though your browser gives you
this capability for HTML already, you cannot view the source code of
executables (like CGIs). This is generally a good thing, but in
certain environments, like this one or a programming environment,
you want to be able to display code.  
</p>

<p>
With Perl it’s an entirely trivial matter to make a CGI that will
display files. It can be done in one line. The entire CGI script could
look like this.
</p>

<p>
<span
style="background-color:#ff9;font-weight:bold;color:#900;">Do not use
this code. </span>  </p>
          <pre class="code" style="background-color:#fff;">print "Content-type: text/plain\n\n", `cat $ENV{QUERY_STRING}`;</pre>     <p>
  That CGI script (pretend it’s called “one_liner.cgi”) will print the
contents of any file passed as the query string. So you could print
this page, <b>viewer.html</b>, by calling the script this way (if you
were an idiot and really installed it). It would be called like so.  </p>
          <pre class="code" style="background-color:#fff;"><b style="color:#396">http://host.com/one_liner.cgi</b><b
style="color:#A00">?</b><b style="color:#036">viewer.html</b></pre>     <p>
  Anything in the URL that follows the “<b>?</b>” is passed to
<b>%ENV</b>, and to Perl, in <b>$ENV{QUERY_STRING}</b>.
</p>

<p>
Now, you should be saying to yourself, “What!?! You’re a psycho! If I
caught you installing a script like that on my server I’d have you
shot and then deported.” Why?  Because you can call the script like
this.  </p>
          <pre class="code" style="background-color:#fff;"><b style="color:#396">http://host.com/one_liner.cgi</b><b
style="color:#F30">?</b><b style="color:#A00">/usr/bin/*</b></pre>     <p>
  Or worse. Don’t try it. Just be assured it works and that it’s not
even the most dangerous hack possible. If you don’t know any, ask your
sysadmin, but you won’t learn ‘em from me. To use it is to open your
entire server, not just the webserver’s document root, to whomever
wants to see it. You would give them a channel to mess with it and,
depending on your permissions schemes, completely trash it.
</p>

<p>
When using backticks (<b>`</b>) in Perl to execute commands, you give
access to the operating system’s shell to any visitor to your
website. Web visitors are usually anonymous and sometimes malicious.
We could use the multiple argument form of system() or exec() to make
it safer. Without help the script is <u>extremely</u> foolish.
</p>

<p>
Also, you never want to print back anything unless you know what it
is, <b>ever</b>. If you even just echo back, by printing to the
browser page, the $ENV{QUERY_STRING}, you might be causing the browser
to execute embedded <b><script></b> tags. This is usually known
as a cross-site scripting attack.
</p>

<p>
We can make it safe and keep it one line of code (spread out below for
readability) but it becomes hard to understand. So it’s only an
exercise and really not suitable for production.
</p>

<p>
We use “text/html” instead of “text/plain” because some browsers won’t
respect the plain text directive when showing the raw text contents of
an HTML file. We have to provide a <nobr>”<PRE>”</nobr> tag and
then substitute all the opening tags “<” with “&lt;” so our
page will print as plain text.  </p>
        <div class="subtitle"> Code (one line, more or less) </div>  <pre class="code" style="background-color:#fff;"><!--#include virtual="./perlview.cgi?file=viewer_stoopid.cgi&line=none&nohead=1"--></pre>      <p>This isn’t so bright, though it (probably) works. Here are the
different ways it can be called.</p>

<ul>
<li>No file name given:  <a
href="code/viewer_stoopid.cgi">viewer_stoopid.cgi</a> </li>
<li>Inappropriate file name given: <nobr><a
href="code/viewer_stoopid.cgi?/etc/inetd.conf">viewer_stoopid.cgi?/etc/inetd.conf</a></nobr></li>
<li>Dangerous string!: <nobr><a
href="code/viewer_stoopid.cgi?<script>alert('got your cookies')</script>">viewer_stoopid.cgi?<script>alert(‘document.cookie’)</script></a></nobr></li>
<li>Correct usage: the HTML of this page: <nobr><a
href="code/viewer_stoopid.cgi?viewer.html">viewer_stoopid.cgi?viewer.html</a></nobr></li>
</ul>

<p>
It might not work as expected because of our HTML tag hack.
</p>

<p>If we allow for using a module, we can make this approach much more
reliable, if not more readable.</p>         <div class="subtitle"> Code (minimalist, slightly improved) </div>  <pre class="code" style="background-color:#fff;"><!--#include virtual="./perlview.cgi?file=viewer_minimalist.cgi&line=none&nohead=1"--></pre>      <p>So, even though it’s jazzed up, it’s still basically a one-liner that
flows like this.</p>

<ol>
 <li>Initialize module <a
href="http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm">HTML::Entities</a>;
we’ll use encode_entities() from it.</li>

<li>Print content header to browser (and body begins with a
<nobr>”<PRE>”</nobr> tag), correctly configured servers will
error out unless
the content-type is delivered in the page header.</li>

<li>Match the query string.
<ol type="a">
<li>If it doesn’t match a conservative file name regex (dots, dashes
and alphanumerics only and leads with a \w) then print <b>You must
provide a valid filename</b>, this also happens when filename is
missing.</li></ol>
</li>

<li>If it does match the regex but doesn’t exist in the same dir,
report <b>There is no file: <i>blank</i></b>.</li>
<li>If it does exist, `cat` it and convert HTML characters to print
correctly</li>
</ol>
<br />     <p class="subtitle"> -T, the taint flag </p>    <p>You might have noticed we didn’t use the <b>-T</b>(aint) flag. It’s
a good idea to have it in all your CGIs. It requires that we check all
our variables, especially environmental ones, to be sure we’ve at
least looked at everything the script is doing. It isn’t a security
blanket but it’s a good seatbelt. And it doesn’t make your scripts
secure, it merely forces you to take action (right or wrong) on the
most vulnerable parts.</p>

<p>
Even in this short space we’ve made a program that is fairly secure
and gives prominent user feedback when used incorrectly.</p>

<ul>
<li>No file name given: <a
href="code/viewer_minimalist.cgi">viewer_minimalist.cgi</a> 
<li>Non existent file name given: <nobr><a
href="code/viewer_minimalist.cgi?porn_in_the_usa">viewer_minimalist.cgi?porn_in_the_usa</a></nobr>
<li>Correct usage: the HTML of this page: <nobr><a
href="code/viewer_minimalist.cgi?viewer.html">viewer_minimalist.cgi?viewer.html</a></nobr>
</ul>

<p>We could even simplify the script by printing “text/plain” instead of
“text/html.” We would be able to dispense with the HTML::Entities if
we did. We could do away with the map, split bit too. The
<nobr><H2>s</nobr> for error messages would have to go though
and they clarify the usage well. Plus the browser might not respect
the “text/plain” content and display the page wrong anyway because its
text begins <nobr>”<HTML>.”</nobr></p>     <p class="subtitle"> Are we there yet? </p>   <p>
  So the second stab is okay. It’s simple. It works. It’s probably not
be the kind of thing we’d want in production but you never know. We
might like more features and expandability. Fixing or extending the
code shown would be an unpleasant excercise.
</p>

<p>
I’ve seen some wonderful code examples posted online. Often they have
line numbers included. This helps when discussing the code but it is a
pain in the rear (unless you’re fast with the -F switch or awk) to
copy and paste. So, I’d like a viewer script that will display with
lines or without. Also, some kids only number the lines with code and
others number all the lines literally. We’d better provide for both of
those as well. And since it’s a viewer, how about its default being to
show its own code?
</p>

<p>
As you might already know from playing with it, the viewer used in
these pages for code does these things. Without further ado, <a
href="viewer.cgi">viewer.cgi</a>; and for colored code, the new and
improved <a href="perlview.cgi">perlview.cgi</a>!  </p>
    <p class="subtitle"> Discussion </p>   <p>
  There are some more general CGI <a href="cgi.html">usage notes and
discussion here</a>.  </p>
   </td>
  </tr><tr>
  <td class="bottom" colspan="2">
<form action="/perl/code/google.cgi" method="get"
 style="margin:0 0 1ex 0;padding:0">
<b>Search these pages via <a
href="http://google.com">Google</a>™</b>
<input type="text" name="search_google"
 onmouseover="this.focus()"
 style="width:15em;font-size:80%;font-weight:bold;padding:2px" />
<input type="submit" value="go" />
</form>  <div id="footlinks">
<a href="bib.html">Perl Books</a> ·
<a href="http://search.cpan.org">CPAN</a> ·
<a href="http://perl.apache.org/">mod_perl</a> ·
<a href="http://www.perlmonks.org/">Perl Monks</a> ·
<a href="http://www.perl.org/">Perl Mongers</a> ·
<a href="http://www.tpj.com/">Perl Journal</a> ·
<a href="http://use.perl.org/">Use Perl</a> ·
<a href="/perl/perl-jobs.html">Perl Jobs</a> ·
<a href="http://www.activestate.com/">ActiveState</a> ·
<a href="http://perldoc.perl.org/">perldoc.perl.org</a>  ·
<a href="http://www.perl.com/">O’Reilly Perl</a> ·
<a href="http://www.w3schools.com/">W3Schools tutorials</a>  ·
<a href="http://users.easystreet.com/ovid/cgi_course/">Ovid's CGI Course</a> ·
<a href="http://catalystframework.org/">Catalyst</a> ·
<a href="http://en.wikipedia.org/wiki/Perl">Perl at Wikipedia</a>
</div>

Text, original code, fonts, and graphics ©1990-2009 <a
href="mailto:perl@sedition.com">Ashley Pond V</a>.  </td>


</tr></table>

</body>
</html>