Opening a unique dat file for each user

R

Regent

Hi,

Depending on the user ID, a unique file is to be opened for
write/append. I use the -T switch for each script, and when the script
goes to this line:

open (F, ">> $root/$path/$uid.dat") or die "$!\n";

# where $uid is the user ID, and I want to use this ID as the file name

I get a warning message saying "Insecure dependency in open while
running with -T switch" and the script terminates. What should I do in
order to avoid this while keeping the taint mode? Thanks.

Regent
 
D

Dave Cross

Hi,

Depending on the user ID, a unique file is to be opened for
write/append. I use the -T switch for each script, and when the script
goes to this line:

open (F, ">> $root/$path/$uid.dat") or die "$!\n";

# where $uid is the user ID, and I want to use this ID as the file name

I get a warning message saying "Insecure dependency in open while
running with -T switch" and the script terminates. What should I do in
order to avoid this while keeping the taint mode? Thanks.

How do the variables $root, $path and $uid get set? You probably need to
untaint one of those.

See "perldoc perlsec" for more details.

Dave...
 
R

Regent

$root and $path are consants, the only variable is $uid, getting its
value in this way:

use CGI qw:)standard);
my $q = new CGI;
my $uid = $q->param('uid');

perlsec tells me that $uid is tainted; but how can I untaint it, if the
received value is to be used, dynamically, as part of a filename?

Thanks for the reply but I don't seem to get the knack...

Regent
 
C

chris-usenet

Regent said:
$root and $path are consants, the only variable is $uid, getting its
value in this way:
use CGI qw:)standard);
my $q = new CGI;
my $uid = $q->param('uid');
perlsec tells me that $uid is tainted

It also gives you examples of how to untaint a tainted value
but how can I untaint it, if the received value is to be used,
dynamically, as part of a filename?

Basically, you shouldn't be trusting the value of $uid, as it's been
supplied by the user. (Consider $uid = "../../../../../../../etc/mime-magic",
or maybe worse.)

You need to decide what the possible values of $uid should be, and ensure
you grab only those:

my $uid = $q->param('uid'); # Tainted
if ($uid =~ /^(\d{1,5})$/) {
$uid = $1 +0; # Untainted in range 0..99999
}
else {
die "Bad data for uid: '$uid'";
}

The RE requires an explicit match to between one and five digits, putting
the matching data (if any) into $1. If you wanted to ensure $uid was in
the range (e.g.) 100 to 65535, then you could extend the if clause to
something like this:

if ($uid =~ /^(\d{1,5})$/ and $1 >= 100 and $1 < 65536) { ... }

Chris
 
K

ko

Don't top-post. Look at how your post was re-arranged - it makes it
easier for people to follow the thread...
$root and $path are consants, the only variable is $uid, getting its
value in this way:

use CGI qw:)standard);
my $q = new CGI;
my $uid = $q->param('uid');

perlsec tells me that $uid is tainted; but how can I untaint it, if
the received value is to be used, dynamically, as part of a filename?

Did you just read the whole document, specifically the section
'Laundering and Detecting Tainted Data'?

Create a regular expression and use the subpattern(s) from the match.
But make *sure* that you use a regex that tests for what you consider
*valid* values. For example, you could technically do something like:

# *don't* do this
$uid = $1 if $uid =~ /(.*)/;

And your program will run, assuming there aren't any other errors. But
that defeats the purpose of using taint mode, since it matches
everything. You need to make a *careful* decision on what values you
feel are appropriate within the context of your application, and then
apply the regex to $uid.
Thanks for the reply but I don't seem to get the knack...

And since you're doing CGI, re-read perlsec till you do 'get the knack'.
That should have been step one in the process...

HTH - keith
 
R

Regent

ko said:
Don't top-post. Look at how your post was re-arranged - it makes it
easier for people to follow the thread...



Did you just read the whole document, specifically the section
'Laundering and Detecting Tainted Data'?

Create a regular expression and use the subpattern(s) from the match.
But make *sure* that you use a regex that tests for what you consider
*valid* values. For example, you could technically do something like:

# *don't* do this
$uid = $1 if $uid =~ /(.*)/;

And your program will run, assuming there aren't any other errors. But
that defeats the purpose of using taint mode, since it matches
everything. You need to make a *careful* decision on what values you
feel are appropriate within the context of your application, and then
apply the regex to $uid.


And since you're doing CGI, re-read perlsec till you do 'get the knack'.
That should have been step one in the process...

HTH - keith

Thanks really. In fact before being used as part of the filename, $uid
is validated beforehand. So

$uid = $1 if $uid =~ /(.*)/;

should be no problem. I tried this, and the script seems sound and safe.
But is there any other potential danger in doing this? I see none at the
moment now.

Regent
 
B

Ben Morrow

Regent said:
Thanks really. In fact before being used as part of the filename, $uid
is validated beforehand. So

$uid = $1 if $uid =~ /(.*)/;

should be no problem. I tried this, and the script seems sound and safe.
But is there any other potential danger in doing this? I see none at the
moment now.

Whenever possible you should make your untaint regex do at least a
reasonable validation: it's *much* *much* safer. At least exclude /:

$uid = $1 if $uid =~ m:([^/]*):;

Ben
 
R

Regent

Greg said:
I am not sure if you mean that you were validating $uid earlier in
your Perl program or by some external means before it gets submitted
such as with Javascript running client-side. I just wanted to point
out that you should never trust data coming from the client, even if
you check it with JS or something.

Anyone familiar with web programming at all could read the source of
your front end(the HTML) and make their own version which sends back
whatever they want, and call it uid(which you are trusting). There are
even programs out there you can download which will automate this
process of hacking web forms. I have even gone to a conference where
they discussed how to hack web forms in detail.

As I said, it wasn't clear to me if you were validating that variable
in your Perl code or checking it before your Perl gets it but if it is
the latter you should check it thoroughly in your Perl anyway.

-Greg

I mean this: in the same script, $uid firstly goes through -T check, and
then compared with the array of authenticated user names in a database.
After all these have been done, what are other problems may the script have?

Cheers,
Regent
 
G

gnari

[snip discussion about untainting]
I mean this: in the same script, $uid firstly goes through -T check, and
then compared with the array of authenticated user names in a database.

this sounds good. after you have made adequate tests on the variable,
if it allright to untaint it as in the example above. I would keep the
untainting
close to the other checks, to make clear that they are connected, so that
future maintainance doesen't make a security hole. the same arguments
apply for more specific untaint, like
$uid = $1 if $uid =~ m!([^/]*)!;

gnari
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top