I stumbled over a nasty bug in CGI.pm today. The kind of bug that surprises me not only because it's there, but because I never stumbled over it sooner. Turns out if you try to pass a '-' (dash) as a URL parameter value, and your script is running with the 'T' (taint) flag, then CGI->new dies with:

Insecure dependency in require while running with -T switch at /usr/lib/perl5/vendor_perl/5.10.0/CGI.pm line 516

This happens in version 3.33 (which I'm running) and doesn't appear to be corrected in the latest 3.42 version. A bug report was posted Mar 25 of this year, so at least I'm not the first to hit it. The problem boils down to this particular section of code:

496: sub init { ... 516: for my $fh (grep {defined(fileno($_))} @$val) { 517: seek($fh,0,0); # reset the filehandle. 518: }

The init() function walks through all query parameters and attempts to reset the file handle for each file name matching the parameter value. The parameter values are obviously tainted as they come from outside the script so using them as input to fileno() already has a funny smell to it. The init() function is called by the new() function, so near as I can tell, this only affects you if you if you use the object interface to CGI (my $obj = CGI->new). Maybe that's one reason why more people aren't complaining?

But CGI doesn't die on all URL values, just '-'. I did a little more digging and sure enough fileno() is called with every URL value, but only '-' caused an insecure dependancy compaint. So I wrote up a script so I could test further:

#!/usr/bin/perl -T use strict; use warnings; # snipped directly from CGI.pm # $val comes from (tained) URL parameters this this case # I'm using command line input to provide tainted test input my $val = \@ARGV; for my $fh (grep {defined(fileno($_))} @$val) { seek($fh,0,0); # reset the filehandle. }

Go ahead, try it yourself. I can pass all kinds of tainted values to fileno(), and none of them are flagged, except '-'.

So my observations are:

  • This affects you if you use the CGI object interface
  • ALL url parameter values are passed into fileno() tainted
  • This code executes in the CGI init() method (called from CGI->new), so you have no control over validating input before CGI processes it
  • My solution is to pass a value into new, "my $obj = CGI->new('')", which is enough to trigger a different logic path which doesn't involve reseting file handles (it doesn't matter that the parameter passed into new is empty, just that it's defined).

    But I feel there are questions that need answering here:

  • Why does fileno() flag '-' as tainted and not other values? Surely it's not testing the values before testing for taintness?
  • Is there a scenario where CGI could mess with the application file handles (or at least die again) because of particular values in the URL?
  • This strikes me needless code execution at best, and as a major security risk at worse. How has it been allowed to slip by without anyone noticing?

  • In reply to fileno, taint and CGI.pm by ruzam

    Title:
    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.