Skip Menu |

This queue is for tickets about the FindBin CPAN distribution.

Report information
The Basics
Id: 60892
Status: open
Priority: 0/
Queue: FindBin

People
Owner: Nobody in particular
Requestors: JNW [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: $FindBin::RealBin is tainted
FindBin-1.50 as included in perl-5.12.1 fails under -T if I use it as suggested in the POD: use FindBin qw($RealBin); use lib "$RealBin/../lib"; This ugly workaround helps: use FindBin; BEGIN { unshift @INC, "$1/../lib" if $FindBin::RealBin =~ m{(.*)} };
On Mon Aug 30 14:45:01 2010, JNW wrote: Show quoted text
> FindBin-1.50 as included in perl-5.12.1 fails under -T if I use it as > suggested in the POD: > > use FindBin qw($RealBin); > use lib "$RealBin/../lib"; > > This ugly workaround helps: > > use FindBin; > BEGIN { unshift @INC, "$1/../lib" if $FindBin::RealBin =~ m{(.*)} };
I can't reproduce this with 5.12.1 or any other version of Perl. Are you sure that you've shown everything necessary to reproduce the problem? Since the information from FindBin is coming from outside the program's control, it would be fitting if it were tainted. It is essentially parsing $0 which is tainted.
CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Mon, 30 Aug 2010 13:57:32 -0700
To: Michael G Schwern via RT <bug-FindBin [...] rt.cpan.org>
From: Ilya Zakharevich <nospam-abuse [...] ilyaz.org>
On Mon, Aug 30, 2010 at 04:43:44PM -0400, Michael G Schwern via RT wrote: Show quoted text
> Queue: FindBin > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=60892 > > > On Mon Aug 30 14:45:01 2010, JNW wrote:
> > FindBin-1.50 as included in perl-5.12.1 fails under -T if I use it as > > suggested in the POD: > > > > use FindBin qw($RealBin); > > use lib "$RealBin/../lib"; > > > > This ugly workaround helps: > > > > use FindBin; > > BEGIN { unshift @INC, "$1/../lib" if $FindBin::RealBin =~ m{(.*)} };
> > I can't reproduce this with 5.12.1 or any other version of Perl. Are > you sure that you've shown everything necessary to reproduce the problem? > > Since the information from FindBin is coming from outside the program's > control, it would be fitting if it were tainted. It is essentially > parsing $0 which is tainted.
I do not see why it should be tainted on systems where the supplied path is reliable. On such systems, the information would be "outside of program's control" only if the caller is able to rename perl... Hope this helps, Ilya
CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Mon, 30 Aug 2010 14:04:53 -0700
To: Ilya Zakharevich via RT <bug-FindBin [...] rt.cpan.org>
From: Ilya Zakharevich <nospam-abuse [...] ilyaz.org>
On Mon, Aug 30, 2010 at 04:57:41PM -0400, Ilya Zakharevich via RT wrote: Show quoted text
> > Since the information from FindBin is coming from outside the program's > > control, it would be fitting if it were tainted. It is essentially > > parsing $0 which is tainted.
> > I do not see why it should be tainted on systems where the supplied > path is reliable. On such systems, the information would be "outside > of program's control" only if the caller is able to rename perl...
Silly me, I was confusing $^X with $0... But the analysis remains: if the caller is able to change $0, all bets are off anyway. Sorry, Ilya
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Mon, 30 Aug 2010 16:08:10 -0500
To: bug-FindBin [...] rt.cpan.org
From: Graham Barr <gbarr [...] pobox.com>
On Aug 30, 2010, at 15:57 , Ilya Zakharevich via RT wrote: Show quoted text
> Queue: FindBin > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=60892 > > > On Mon, Aug 30, 2010 at 04:43:44PM -0400, Michael G Schwern via RT wrote:
>> Queue: FindBin >> Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=60892 > >> >> On Mon Aug 30 14:45:01 2010, JNW wrote:
>>> FindBin-1.50 as included in perl-5.12.1 fails under -T if I use it as >>> suggested in the POD: >>> >>> use FindBin qw($RealBin); >>> use lib "$RealBin/../lib"; >>> >>> This ugly workaround helps: >>> >>> use FindBin; >>> BEGIN { unshift @INC, "$1/../lib" if $FindBin::RealBin =~ m{(.*)} };
>> >> I can't reproduce this with 5.12.1 or any other version of Perl. Are >> you sure that you've shown everything necessary to reproduce the problem? >> >> Since the information from FindBin is coming from outside the program's >> control, it would be fitting if it were tainted. It is essentially >> parsing $0 which is tainted.
> > I do not see why it should be tainted on systems where the supplied > path is reliable. On such systems, the information would be "outside > of program's control" only if the caller is able to rename perl...
Not true. FindBin::RealBin is the bin directory of the script, not the perl executable $FindBin::Bin almost certainly should be tainted on any system which provides symlinks or similar. Also if $0 is not the full path, the $ENV{PATH} will be used, so again it should be tainted. Graham.
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Mon, 30 Aug 2010 16:55:20 -0700
To: bug-FindBin [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
On 2010.8.30 2:05 PM, Ilya Zakharevich via RT wrote: Show quoted text
> Queue: FindBin > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=60892 > > > On Mon, Aug 30, 2010 at 04:57:41PM -0400, Ilya Zakharevich via RT wrote:
>>> Since the information from FindBin is coming from outside the program's >>> control, it would be fitting if it were tainted. It is essentially >>> parsing $0 which is tainted.
>> >> I do not see why it should be tainted on systems where the supplied >> path is reliable. On such systems, the information would be "outside >> of program's control" only if the caller is able to rename perl...
> > Silly me, I was confusing $^X with $0... But the analysis remains: if > the caller is able to change $0, all bets are off anyway.
Tainting does not make value judgments like that. Going down that road, what if the data is coming from a file that the process owner owns and its set only owner writable? Certainly sounds safe, why taint it? What if an attacker tricked the process (or another process) into writing that file? All bets are not off if $0 can be changed. Initial breeches are usually very narrow and specific and rely on bootstrapping from that small hole into more and more privileges. As Graham pointed out, maybe you tricked a program into running a linked file with a poisoned name. Tainting would stop the attacker from bootstrapping further, if detainting is doing its job. [2] If it comes from outside the program, it is tainted. [1] This is a bit tautological, but it keeps things simple and it avoids making probably invalid assumptions about how the data and program are going to be used. There is the narrower issue. FindBin *could* detaint for the user. It probably sometimes already does accidentally, which is why I can't reproduce this issue. This too makes assumptions about how the data is going to be used. One could make this safer by encoding those assumptions and safety checks. That is, make a FindBin function which is all about setting up @INC. use FindBin qw(bin_to_lib); bin_to_lib("..", "lib"); That would be the equivalent of: use FindBin; use lib "$FindBin::Bin/../lib"; but with everything detainted and done in a cross platform manner and making its assumptions about how the detainted data will be used explicit. [1] With mostly unfortunate exceptions due to implementation. [2] That is, forcing the programmer to consider and handle security implications of untrusted data. -- ROCKS FALL! EVERYONE DIES! http://www.somethingpositive.net/sp05032002.shtml
CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Mon, 30 Aug 2010 17:21:49 -0700
To: Michael G Schwern via RT <bug-FindBin [...] rt.cpan.org>
From: Ilya Zakharevich <nospam-abuse [...] ilyaz.org>
On Mon, Aug 30, 2010 at 07:55:41PM -0400, Michael G Schwern via RT wrote: Show quoted text
> > Silly me, I was confusing $^X with $0... But the analysis remains: if > > the caller is able to change $0, all bets are off anyway.
Show quoted text
> Tainting does not make value judgments like that. Going down that road, what > if the data is coming from a file that the process owner owns and its set only > owner writable? Certainly sounds safe, why taint it? What if an attacker > tricked the process (or another process) into writing that file?
Of course tainting DOES value judgements. Does it check whether CRTL is one which is expected? Does it check that there are not hot-fixes to Perl's DLL? (Possible on Solaris.) Does it check that things are not maliciously chroot()ed? Show quoted text
> All bets are not off if $0 can be changed. Initial breeches are usually very > narrow and specific and rely on bootstrapping from that small hole into more > and more privileges. As Graham pointed out, maybe you tricked a program into > running a linked file with a poisoned name.
It is still not clear to me how this would be possible, but replacing the script by a different one is not. Show quoted text
> Tainting would stop the attacker from bootstrapping further, if > detainting is doing its job. [2]
Seeing the code you propose below, I do not see how it would stop anyone... Show quoted text
> use FindBin qw(bin_to_lib); > bin_to_lib("..", "lib");
[OT: not clear why you think it is better than use FindBin; FindBin::bin_to_lib("..", "lib"); ...] Show quoted text
> That would be the equivalent of: > > use FindBin; > use lib "$FindBin::Bin/../lib"; > > but with everything detainted and done in a cross platform manner and making > its assumptions about how the detainted data will be used explicit.
And making as great a security hole as one had when $0 was untainted... I do not see any solutin except for having use FindBin; FindBin::untainted_bin_to_lib '../lib'; (as you see, I see no point in manually breaking into components when untainted_bin_to_lib() can split on '/' anyway). Yours, Ilya
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Tue, 31 Aug 2010 02:53:13 -0700
To: bug-FindBin [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
On 2010.8.30 5:21 PM, Ilya Zakharevich via RT wrote: Show quoted text
> Queue: FindBin > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=60892 > > > On Mon, Aug 30, 2010 at 07:55:41PM -0400, Michael G Schwern via RT wrote:
>>> Silly me, I was confusing $^X with $0... But the analysis remains: if >>> the caller is able to change $0, all bets are off anyway.
>
>> Tainting does not make value judgments like that. Going down that road, what >> if the data is coming from a file that the process owner owns and its set only >> owner writable? Certainly sounds safe, why taint it? What if an attacker >> tricked the process (or another process) into writing that file?
> > Of course tainting DOES value judgements. Does it check whether CRTL is > one which is expected? Does it check that there are not hot-fixes to > Perl's DLL? (Possible on Solaris.) Does it check that things are not > maliciously chroot()ed?
While those are security concerns, those are not "data coming from outside the program" which is all tainting is really about. Tainting has nothing to say about any of that. If you want to talk about expanding the scope of tainting, or adding additional security checks to Perl, or the value of taint in general, that's a whole other issue. Show quoted text
>> All bets are not off if $0 can be changed. Initial breeches are usually very >> narrow and specific and rely on bootstrapping from that small hole into more >> and more privileges. As Graham pointed out, maybe you tricked a program into >> running a linked file with a poisoned name.
> > It is still not clear to me how this would be possible, but replacing > the script by a different one is not.
When it comes to security, I find I'm usually not smart enough to see the holes either. So I'm perfectly happy with leaving everything sealed up tight. $0 need not have been attacked and changed. You could be generating programs with filenames based on user input (I've seen sillier things) and someone slipped in some input that causes your filename to be "rm -rf /;" in the hopes you'll use the filename in a system call. Its a stretch, but I've seen crazier things. The temp file attacks that cropped up a while back, all relying on very well timed file replacements and very subtle slips in temp file handling. Show quoted text
>> Tainting would stop the attacker from bootstrapping further, if >> detainting is doing its job. [2]
> > Seeing the code you propose below, I do not see how it would stop anyone...
Sorry, I was misleading about what it does. bin_to_lib() would leave everything outside tainted. $0 remains tainted. $FindBin::Bin remains tainted. It *only* detaints for the specific purpose of pushing $FindBin::Bin/../lib onto @INC so that @INC does not catch $0's taint. I don't think that's any more exploitable than the whole idea of FindBin is to begin with. I could be wrong, but its better than people blindly untainting $FindBin::Bin as the original reporter was. The important bit is that because we don't know how they'll be used, it leaves $FindBin::Bin and friends tainted for the rest of the program. Here's what it might look like: sub bin_to_lib { my @lib = @_; # Is there any checks we can do here? # Can anything malicious be put into @INC? my($bin) = $FindBin::Bin =~ /(.*)/; require lib; lib->import(File::Spec->catdir($bin, $lib)); return 1; } Does that clear things up? Show quoted text
>> That would be the equivalent of: >> >> use FindBin; >> use lib "$FindBin::Bin/../lib"; >> >> but with everything detainted and done in a cross platform manner and making >> its assumptions about how the detainted data will be used explicit.
> > And making as great a security hole as one had when $0 was untainted... > > I do not see any solutin except for having > use FindBin; > FindBin::untainted_bin_to_lib '../lib'; > (as you see, I see no point in manually breaking into components when > untainted_bin_to_lib() can split on '/' anyway).
How the file path is handled can go either way. Its not really important. Show quoted text
>> use FindBin qw(bin_to_lib); >> bin_to_lib("..", "lib");
> > [OT: not clear why you think it is better than > use FindBin; > FindBin::bin_to_lib("..", "lib"); > ...]
In this specific case, with a very short module name, it really doesn't matter much one way or the other. -- 52. Not allowed to yell "Take that Cobra" at the rifle range. -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army http://skippyslist.com/list/
CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Tue, 31 Aug 2010 14:47:42 -0700
To: Michael G Schwern via RT <bug-FindBin [...] rt.cpan.org>
From: Ilya Zakharevich <nospam-abuse [...] ilyaz.org>
On Tue, Aug 31, 2010 at 05:53:27AM -0400, Michael G Schwern via RT wrote: Show quoted text
> > Seeing the code you propose below, I do not see how it would stop anyone...
Show quoted text
> Sorry, I was misleading about what it does.
Show quoted text
> bin_to_lib() would leave everything outside tainted. $0 remains tainted. > $FindBin::Bin remains tainted. It *only* detaints for the specific purpose of > pushing $FindBin::Bin/../lib onto @INC so that @INC does not catch $0's taint. > I don't think that's any more exploitable than the whole idea of FindBin is > to begin with.
The key thing is "any more exploitable than the whole idea of modules sitting near executables". My point is that you target an insignificant crack (tainting $0) while one has the whole abyss sitting next to it. Some first questions coming to mind: should FindBin follow all the symlinks? Should bin_to_lib have a (required) option limiting modules which may be loaded from the found directory? Show quoted text
> > I do not see any solutin except for having > > use FindBin; > > FindBin::untainted_bin_to_lib '../lib'; > > (as you see, I see no point in manually breaking into components when > > untainted_bin_to_lib() can split on '/' anyway).
Show quoted text
> How the file path is handled can go either way. Its not really important.
The accent was on having "untaint" inside the name, so the composer of the script has a chance to stop to think. Or better, "unsecure_bin_to_lib". Yours, Ilya P.S. Show quoted text
> >> use FindBin qw(bin_to_lib); > >> bin_to_lib("..", "lib");
Show quoted text
> > [OT: not clear why you think it is better than > > use FindBin; > > FindBin::bin_to_lib("..", "lib"); > > ...]
Show quoted text
> In this specific case, with a very short module name, it really doesn't matter > much one way or the other.
I'm just curious: myself, I find full names more pleasant for call-once situation notwithstanding the module name...
CC: JNW [...] cpan.org
Subject: Re: [rt.cpan.org #60892] $FindBin::RealBin is tainted
Date: Thu, 2 Sep 2010 23:02:46 +0200
To: Michael G Schwern via RT <bug-FindBin [...] rt.cpan.org>
From: Juergen Weigert <jw [...] suse.de>
On Aug 30, 10 16:43:44 -0400, Michael G Schwern via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=60892 > > > On Mon Aug 30 14:45:01 2010, JNW wrote:
> > FindBin-1.50 as included in perl-5.12.1 fails under -T if I use it as > > suggested in the POD: > > > > use FindBin qw($RealBin); > > use lib "$RealBin/../lib"; > > > > This ugly workaround helps: > > > > use FindBin; > > BEGIN { unshift @INC, "$1/../lib" if $FindBin::RealBin =~ m{(.*)} };
> > I can't reproduce this with 5.12.1 or any other version of Perl. Are > you sure that you've shown everything necessary to reproduce the problem?
one more step is missing in the above. There needs to be a line use Something; that pulls Something.pm in from the newly added lib directory. Show quoted text
> Since the information from FindBin is coming from outside the program's > control, it would be fitting if it were tainted. It is essentially > parsing $0 which is tainted.
Hmm. I agree that this is a sane default. I seek a way to express, "I want to consider my '../lib' as okay." Compare with FindBin::libs - which always silently untaints its results. There seems to be a need :-) cheers, JW- -- o \ Juergen Weigert paint it green! __/ _=======.=======_ <V> | jw@suse.de back to ascii! __/ _---|____________\/ \ | 0911 74053-508 __/ (____/ /\ (/) | _____________________________/ _/ \_ vim:set sw=2 wm=8 SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg) "You are trying to use packages from project 'openSUSE:11.3'. Note that malicious packages can compromise your system."