Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
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 making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2015-07-05 09:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (61 votes), past polls