Taint Mode Newbie Help

Discussion in 'Perl Misc' started by sekdab, Jul 19, 2003.

  1. sekdab

    sekdab Guest

    Hello all.

    I am teaching myself Perl and have written a CGI script that allows a
    user to change his/her Apache password by calling "htaccess" in batch
    mode via a set of backticks (intranet only!).

    The script is running perfectly, however, I'd really like to place it
    in taint mode so that I can learn the right way. However, when I do
    that, it breaks. Here is a snippet where things go amiss:

    $!/opt/perl/bin/perl -wT
    use strict;
    use CGI;
    my $pass=$q->param("pass");
    my $pass_ck=$q->param("pass_ck");
    my $user=$q->remote_user;
    my $pcmd='/opt/apache/bin/htpasswd -b';
    my $auth='/usa/auth/passwd';
    $ENV{PATH}='/usr/bin';

    #... - Subroutines to Create HTML Snipped out - ...#

    if ( $pass && $pass_ck ) {
    if ( $pass eq $pass_ck ) {
    if ( $pass =~ /^[A-Za-z0-9]+$/ ) {
    $pass = $1;
    my $output=`$pcmd $auth $user $pass 2>&1`;
    chomp($output);
    if ( $output eq "Updating password for user $user" ) {
    print "PASSWORD CHANGE OKAY";
    } else {
    print "ERROR CHANGING PASSWORD";
    }
    } else {
    print "PASSWORD FAILED - NON ALPHANUMERIC";
    }
    } else {
    print "PASSWORDS DO NOT MATCH";
    }
    }

    The form is basically, "enter new password," "enter new password
    again," and "submit." So, first I ensure that the passwords entered
    are not null, and then verify that they match. After that (the third
    if) I try to untaint the $pass variable.

    I check to ensure that it is alphanumeric and then assign it to $1.
    After which, I place it in the shell execution backticks. However,
    both $1 and $pass are null now, and the execution fails.

    The error coming from Perl is:

    "Use of uninitialized value in concatenation (.) or string at
    /usa/perl/change_pass.pl line 67."

    That line is where I declare and set $ouput (i.e. the backtick
    execution).

    I'm stumped. I really want to learn this the right way first time
    around and get things working with taint. I love the concept behind
    it, just having trouble with the implementation.

    My appreciation for any assistance,
    Tom
     
    sekdab, Jul 19, 2003
    #1
    1. Advertising

  2. sekdab

    Jay Tilton Guest

    (sekdab) wrote:

    : if ( $pass =~ /^[A-Za-z0-9]+$/ ) {
    : $pass = $1;
    # snip
    : }

    : I check to ensure that it is alphanumeric and then assign it to $1.
    : After which, I place it in the shell execution backticks. However,
    : both $1 and $pass are null now, and the execution fails.

    $1 does not get defined unless there is a set of capturing parentheses
    in the regex.

    if ( $pass =~ /^([A-Za-z0-9]+)$/ ) {
    $pass = $1;
    # snip
    }
     
    Jay Tilton, Jul 19, 2003
    #2
    1. Advertising

  3. sekdab

    sekdab Guest

    Hi all.

    Okay.. I posted the previous question half asleep after working on
    this for awhile. My apologies. I'm going to try and rephrase this
    now that I've had (a lot) of coffee :).

    I've written a CGI script that allows a user to change his/her Apache
    password by calling "htpasswd -b" from the shell. The script runs
    without any trouble. However, when I add the -T (taint) option, it
    dies.

    I have been trying to untaint this but have had no luck. I've read
    'perlsec' and followed the example, but just can't get this to go.
    I'm new at all of this, so am probably missing something obvious, but
    if anyone could help, that'd be great. The working code is posted
    below, without taint enabled. A basic outline is:

    -Define modules and variables
    -Subroutine for HTML Header
    -Subroutine for HTML Table
    -Call Subroutines to create HTML
    -*** Validate User Input *** <--- This is the area which I can't
    figure out.
    What I do here is...
    1) Ensure that values are not null
    2) Ensure that the re-enter password matches the first one
    3) Ensure that the data being passed to `` is alphanumeric
    4) Ensure that htpasswd -b ran okay
    -Call HTML Footer

    It is fairly obvious that the $pass variable is the one being tainted.
    It is received from the user via a form and then passed to a shell.
    So, what I've been trying to do is untaint it. I've tried stuff
    like...

    $pass = $1;

    after the if logic. That takes away the taint within the backticks,
    but sets $pass to undefined. I'm utterly confused :-(. Thanks for
    any help that can be given. The code, in its entirety, is posted
    below:

    Regards,
    Tom

    =======================CODE BELOW=========================

    #!/opt/perl/bin/perl -w
    use strict;
    use CGI;
    my $q=new CGI;
    my $pass=$q->param("pass");
    my $pass_ck=$q->param("pass_ck");
    my $user=$q->remote_user;
    my $pcmd='/opt/apache/bin/htpasswd -b';
    my $auth='/usa/auth/passwd';
    $ENV{PATH}='/usr/bin';

    # Subroutine - HTML Header Information
    sub create_header {
    print $q->header,
    $q->start_html(
    -Title=>'U.S.A.',
    -Style=>{-src=>'/css/stylesheet.css'} ),
    $q->start_form(-method=>'post', -action=>'change_pass.pl');
    }

    # Subroutine - HTML Table Information
    sub create_table {
    print $q->table(
    $q->Tr( [
    $q->th( {-colspan=>2}, ['Password Administration'] ),
    $q->td( ['Enter Your New Password',
    $q->password_field(-Name=>'pass', -maxlength=>8) ] ),
    $q->td( ['Reenter Your New Password',
    $q->password_field(-Name=>'pass_ck', -maxlength=>8) ] ),
    $q->td( [$q->submit,$q->button({-Name=>'Close Window',
    -onclick=>'window.close()'} ) ] )
    ] )
    );
    }

    # Subroutine - HTML Footer
    sub create_footer {
    print $q->end_form, $q->end_html;
    }

    # Load Header And Table
    create_header();
    create_table();

    #---------------------------------
    # *** Verify User Input ***
    #---------------------------------
    if ( $pass && $pass_ck ) {
    if ( $pass eq $pass_ck ) {
    if ( $pass =~ /^[A-Za-z0-9]+$/ ) {
    my $output=`$pcmd $auth $user $pass 2>&1`;
    chomp($output);
    if ( $output eq "Updating password for user $user" ) {
    print "<script>window.location.href='/pass_okay.html'</script>";
    } else {
    print "<script>window.location.href='/pass_error.html'</script>";
    }
    } else {
    print "<script>window.location.href='/pass_invalid.html'</script>";
    }
    } else {
    print "<script>window.location.href='/pass_nomatch.html'</script>";
    }
    }

    # Load Footer
    create_footer();

    #========================END OF CODE========================

    (sekdab) wrote in message news:<>...
    > Hello all.
    >
    > I am teaching myself Perl and have written a CGI script that allows a
    > user to change his/her Apache password by calling "htaccess" in batch
    > mode via a set of backticks (intranet only!).
    >
    > The script is running perfectly, however, I'd really like to place it
    > in taint mode so that I can learn the right way. However, when I do
    > that, it breaks. Here is a snippet where things go amiss:
    >
    > $!/opt/perl/bin/perl -wT
    > use strict;
    > use CGI;
    > my $pass=$q->param("pass");
    > my $pass_ck=$q->param("pass_ck");
    > my $user=$q->remote_user;
    > my $pcmd='/opt/apache/bin/htpasswd -b';
    > my $auth='/usa/auth/passwd';
    > $ENV{PATH}='/usr/bin';
    >
    > #... - Subroutines to Create HTML Snipped out - ...#
    >
    > if ( $pass && $pass_ck ) {
    > if ( $pass eq $pass_ck ) {
    > if ( $pass =~ /^[A-Za-z0-9]+$/ ) {
    > $pass = $1;
    > my $output=`$pcmd $auth $user $pass 2>&1`;
    > chomp($output);
    > if ( $output eq "Updating password for user $user" ) {
    > print "PASSWORD CHANGE OKAY";
    > } else {
    > print "ERROR CHANGING PASSWORD";
    > }
    > } else {
    > print "PASSWORD FAILED - NON ALPHANUMERIC";
    > }
    > } else {
    > print "PASSWORDS DO NOT MATCH";
    > }
    > }
    >
    > The form is basically, "enter new password," "enter new password
    > again," and "submit." So, first I ensure that the passwords entered
    > are not null, and then verify that they match. After that (the third
    > if) I try to untaint the $pass variable.
    >
    > I check to ensure that it is alphanumeric and then assign it to $1.
    > After which, I place it in the shell execution backticks. However,
    > both $1 and $pass are null now, and the execution fails.
    >
    > The error coming from Perl is:
    >
    > "Use of uninitialized value in concatenation (.) or string at
    > /usa/perl/change_pass.pl line 67."
    >
    > That line is where I declare and set $ouput (i.e. the backtick
    > execution).
    >
    > I'm stumped. I really want to learn this the right way first time
    > around and get things working with taint. I love the concept behind
    > it, just having trouble with the implementation.
    >
    > My appreciation for any assistance,
    > Tom
     
    sekdab, Jul 19, 2003
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Johann C. Rocholl

    Taint (like in Perl) as a Python module: taint.py

    Johann C. Rocholl, Feb 5, 2007, in forum: Python
    Replies:
    5
    Views:
    473
    Johann C. Rocholl
    Feb 6, 2007
  2. Louis Erickson
    Replies:
    2
    Views:
    209
    James Willmore
    Sep 3, 2003
  3. Ben
    Replies:
    17
    Views:
    232
  4. Dave Saville

    Find::File and taint mode

    Dave Saville, Nov 18, 2003, in forum: Perl Misc
    Replies:
    5
    Views:
    134
    Ben Morrow
    Nov 18, 2003
  5. Dave Saville

    Taint mode help

    Dave Saville, May 10, 2012, in forum: Perl Misc
    Replies:
    7
    Views:
    846
    Dave Saville
    May 16, 2012
Loading...

Share This Page