Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Keep It Simple, Stupid
 
PerlMonks  

CGI question: untainting a lot of variables

by coolmichael (Deacon)
on Dec 31, 2001 at 06:40 UTC ( #135316=perlquestion: print w/ replies, xml ) Need Help??
coolmichael has asked for the wisdom of the Perl Monks concerning the following question:

I've hacked together a couple of quick functions to handle untainting data in a cgi script. As I'm still fairly new to CGI, I was wondering if the fellow monks could offer some constructive criticism, specifically, are there any security problems with this (assuming I pass a proper regex)?

sub badinputerror ($) { my $q = shift; print $q->header('text/plain'); print <<"EOHTML"; There was an error with your input. Please try again. EOHTML die "input did not pass taint checking\n"; } sub untaint ($$$) { my $q = shift; my $name = shift; my $re = shift; my $tainted = $q->param($name); my $untainted = undef; $untainted = $1 if($tainted =~ m/^($re)$/); badinputerror($q) unless($untainted); return $untainted; } # # And later on in the code, for example # my $username=untaint($q, 'user', "[a-zA-Z][a-zA-Z0-9_]+");

Comment on CGI question: untainting a lot of variables
Download Code
Re: CGI question: untainting a lot of variables
by belg4mit (Prior) on Dec 31, 2001 at 06:57 UTC
    Is there something wrong with CGI::Untaint?

    --
    perl -pe "s/\b;([st])/'\1/mg"

      The reference to this module was interesting so I decided to check it out. Maybe someone could explain to me if there are any real advantages to using CGI::Untaint in this situation. There's a good chance I'm suffering from brain burnout right now, so apologies if this post turns out to be a Doh! I don't mind being corrected as I'm here to learn.

      I looked into CGI::Untaint but was non-plused by the documentation. Untainting CGI data, if I understand the basic concept, is not a complicated task. In fact, I had assumed that there wasn't an Untaint module (apparently incorrectly) for that very reason. The CGI::Untaint module, OTOH, seems aimed more towards data validation (via Extract) where untainting the data is just a pass through step.

      If all I wanted to do was untaint my CGI params, how would just that one task be accomplished using CGI::Untaint? The documentation is rather vague on that point. The module also appears to be fairly young. Is this a situation where roll-your-own is an acceptable option?

      On a more general note, are there any hard and fast rules for evaluating the suitability of a module for a given task other than by recommendation (assuming we're talking about a beginner at Perl). Specifically, how can you tell if a more recent module has been adequately vetted?

      As an aside, this module doesn't appear to be available directly from Active State via ppm.

      --Jim

        While CGI::Untaint would be good for untainting a mass of variables. It is basicaly more like data validation. To me after looking at CGI::Untaint's documentation it bears a resemblance to a very basic version of Data::FormValidator and is obsoleted by it. Data::FormValidator can be given a regex as a rule to check the input value of a form field. For example:
        use strict; use CGI; use Data::FormValidator; my $q = new CGI; # hashref of data my $UnsafeData = $q->Vars; my $validator = new Data::FormValidator( "input_profiles.pl" ); my ( $valid, $missing, $invalid, $unknown ) = $validator->validate( $ +UnsafeData, "customer_infos" );
        An example of input_profiles.pl taken from the documentation
        { customer_infos => { optional => [ qw( company fax country password password_con +firmation file_path) ], required => [ qw( fullname phone email address) ], required_regexp => '/city|state|zipcode/', optional_regexp => '/_province$/', constraints => { file_path => '/([-\w.\/]*)/', email => "email", fax => "american_phone", phone => "american_phone", zipcode => '/^\s*\d{5}(?:[-]\d{4})?\s*$ +/', state => "state", }, constraint_regexp_map => { '/_postcode$/' => 'postcode', '/_province$/' => 'province, }, dependency_groups => { password_group => [qw/password password_confirm +ation/] } defaults => { country => "USA", }, } }
        The data in $valid is now considered untainted and all unexpected fields are put in $unknown as an array ref. Read the documentation on Data::FormValidator as this module will not only allow you to set the rules of the data coming in but also weed out the data that you don't want.

        BMaximus
Re: CGI question: untainting a lot of variables
by crazyinsomniac (Prior) on Dec 31, 2001 at 11:28 UTC
    Here is an alternative.
    #!/usr/bin/perl -wlT use strict; use CGI; use CGI::ArgChecker; use Data::Dumper; my $Q = new CGI; my $checker = new CGI::ArgChecker; $checker->register_check('BloT', sub { warn "You *really* are a GENIUS!!! @_"; return 1; }); $checker->error_handler( sub { warn "You are a GENIUS!!! @_"; }); my $chuck = $checker->argcheck( $Q, 'a' => [ 'disallow_empty', 'want_int' ], 'b' => [ 'disallow_empty', 'BloT' ], ,); print Dumper $chuck; __END__ F:\dev\>perl -T argchk.pl a=Where do all the old erections go? -- Adam You are a GENIUS!!! a want_int at argchk.pl line 19. You *really* are a GENIUS!!! SCALAR(0x1bc4610) at argchk.pl line 13. You are a GENIUS!!! b disallow_empty at argchk.pl line 19. You are a GENIUS!!! b BloT at argchk.pl line 19. $VAR1 = { 'ERROR' => 1, 'a' => 'Where', 'b' => undef };
    What can I say, I feel *smart* today `.) (btw, CGI::ArgChecker is a wrapper around String::Checker

     
    ______crazyinsomniac_____________________________
    Of all the things I've lost, I miss my mind the most.
    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Re: CGI question: untainting a lot of variables
by mkmcconn (Chaplain) on Dec 31, 2001 at 11:34 UTC

    It's strictly a style comment, and I apologize for that; but perhaps you might like to abbreviate the work, this way:

    sub untaint ($$$) { my ($q,$name,$re) = @_; my $tainted = $q->param($name); my ($untainted) = $tainted =~ m/^($re)$/); badinputerror($q) unless($untainted); return $untainted; } # $untainted will be undefined if there is no match.
    mkmcconn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://135316]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2014-04-19 15:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (482 votes), past polls