Taint Mode Newbie Help

S

sekdab

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
 
J

Jay Tilton

(e-mail address removed) (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
}
 
S

sekdab

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========================

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top