viewer.html

<?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&eacute;sum&eacute; 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&eacute;sum&eacute;</a> </div> <div class="rightlink"> <a href="resume.html">R&eacute;sum&eacute;</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&#8217;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&#8217;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&#8217;s called &#8220;one_liner.cgi&#8221;) 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 &#8220;<b>?</b>&#8221; is passed to <b>%ENV</b>, and to Perl, in <b>$ENV{QUERY_STRING}</b>. </p> <p> Now, you should be saying to yourself, &#8220;What!?! You&#8217;re a psycho! If I caught you installing a script like that on my server I&#8217;d have you shot and then deported.&#8221; 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&#8217;t try it. Just be assured it works and that it&#8217;s not even the most dangerous hack possible. If you don&#8217;t know any, ask your sysadmin, but you won&#8217;t learn &#8216;em from me. To use it is to open your entire server, not just the webserver&#8217;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&#8217;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>&lt;script&gt;</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&#8217;s only an exercise and really not suitable for production. </p> <p> We use &#8220;text/html&#8221; instead of &#8220;text/plain&#8221; because some browsers won&#8217;t respect the plain text directive when showing the raw text contents of an HTML file. We have to provide a <nobr>&#8221;&lt;PRE&gt;&#8221;</nobr> tag and then substitute all the opening tags &#8220;&lt;&#8221; with &#8220;&amp;lt;&#8221; 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&#8217;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?&lt;script&gt;alert(&#8216;document.cookie&#8217;)&lt;/script&gt;</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&#8217;s jazzed up, it&#8217;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&#8217;ll use encode_entities() from it.</li> <li>Print content header to browser (and body begins with a <nobr>&#8221;&lt;PRE&gt;&#8221;</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&#8217;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&#8217;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&#8217;t use the <b>-T</b>(aint) flag. It&#8217;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&#8217;ve at least looked at everything the script is doing. It isn&#8217;t a security blanket but it&#8217;s a good seatbelt. And it doesn&#8217;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&#8217;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 &#8220;text/plain&#8221; instead of &#8220;text/html.&#8221; 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>&lt;H2&gt;s</nobr> for error messages would have to go though and they clarify the usage well. Plus the browser might not respect the &#8220;text/plain&#8221; content and display the page wrong anyway because its text begins <nobr>&#8221;&lt;HTML&gt;.&#8221;</nobr></p> <p class="subtitle"> Are we there yet? </p> <p> So the second stab is okay. It&#8217;s simple. It works. It&#8217;s probably not be the kind of thing we&#8217;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&#8217;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&#8217;re fast with the -F switch or awk) to copy and paste. So, I&#8217;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&#8217;d better provide for both of those as well. And since it&#8217;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>&trade;</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&nbsp;Books</a> &middot; <a href="http://search.cpan.org">CPAN</a> &middot; <a href="http://perl.apache.org/">mod_perl</a> &middot; <a href="http://www.perlmonks.org/">Perl&nbsp;Monks</a> &middot; <a href="http://www.perl.org/">Perl&nbsp;Mongers</a> &middot; <a href="http://www.tpj.com/">Perl&nbsp;Journal</a> &middot; <a href="http://use.perl.org/">Use&nbsp;Perl</a> &middot; <a href="/perl/perl-jobs.html">Perl&nbsp;Jobs</a> &middot; <a href="http://www.activestate.com/">ActiveState</a> &middot; <a href="http://perldoc.perl.org/">perldoc.perl.org</a> &middot; <a href="http://www.perl.com/">O&#8217;Reilly&nbsp;Perl</a> &middot; <a href="http://www.w3schools.com/">W3Schools&nbsp;tutorials</a> &middot; <a href="http://users.easystreet.com/ovid/cgi_course/">Ovid's&nbsp;CGI&nbsp;Course</a> &middot; <a href="http://catalystframework.org/">Catalyst</a> &middot; <a href="http://en.wikipedia.org/wiki/Perl">Perl at Wikipedia</a> </div> Text, original code, fonts, and graphics &#169;1990-2009 <a href="mailto:perl@sedition.com">Ashley Pond V</a>. </td> </tr></table> </body> </html>