Re: efficient module version checking without loading the module?

2004-03-26 Thread David Nicol
Question: How many ways are there to modify the include-path and
does tainting allow you to set the include-path with tainted
data in any of them and if so can this be repaired?
require() ignores the tainting flag.



Re: efficient module version checking without loading the module?

2004-03-26 Thread David Nicol


Stas Bekman wrote:
In which case using laundering and eval'ing in the Safe compartment is 
probably the best idea. Though if I remember correctly Safe has lots of 
problems (doesn't quite work in certain environments), so I'm not sure 
how practical it is.


What's the advantage of that over opening the file for reading
and looking for /\$VERSION\s*=\s*([^\s\;]+)/ in it?
(adjust the regex some to handle quoting if needed)
Adjusting the version search regex to handle problems such as the
version is deswcribed on multiple lines, or the version is described
within quotes -- workarounds are possible, but it seems like
documenting that that is what your version checker does and doing it
instead of trying to compensate for all edge cases would be a reasonable
approach.
As usual, i might not know what I'm talking about.

--
[EMAIL PROTECTED]
perl


Re: efficient module version checking without loading the module?

2004-03-26 Thread Ken Williams
On Mar 25, 2004, at 3:06 PM, David Nicol wrote:

Question: How many ways are there to modify the include-path and
does tainting allow you to set the include-path with tainted
data in any of them and if so can this be repaired?
Without taint checking, the current working directory and 
$ENV{PERL5LIB} are both put into @INC.  Either of these is suspect.

When taint checking is on, neither is added.  So I think the only 
directories in @INC that's not compiled into the perl binary will come 
from -I switches on the command line (or in the script shebang line).

In perl 5.8.1, -I doesn't seem to taint @INC:

% perl -MScalar::Util=tainted -I/foo/bar -T -le 'print tainted($_) for 
@INC'
0
0
0
0
0
0
0
0
0

Maybe it should?

 -Ken



Re: efficient module version checking without loading the module?

2004-03-25 Thread Martyn J. Pearce
On Wed, Mar 24, 2004 at 12:20:58PM -0800, Stas Bekman wrote:
 I completely agree with you, Hugo. But I'm also sure that you know that 
 when something doesn't work under -T a frustrated user simply turns it off. 
 So:
 
   Well yes it does, in an untainted environment
 
 is really, not it doesn't work. I'd rather relax taint checking in certain 
 places, rather than have the user turn it off completely. Certainly 
 documenting the issue should be helpful.

Whether relxed tainting is superior to no tainting is surely dependent on your
view of tainting, to whit:

1) If tainting is a security measure to prevent malicious attackers (e.g., as
used in suid scripts), then a relaxed tainting provides a false sense of
security, and at least no tainting lets you know that the script is not to be
trusted.

2) If tainting is a bit like warnings, in that it's a helpful warning measure
to assist in catching a number of common issues but not a guarantee of
anything, then as you say, a relaxed taint that's used is better than none at
all.

Mx.


Re: efficient module version checking without loading the module?

2004-03-25 Thread Stas Bekman
Martyn J. Pearce wrote:
On Wed, Mar 24, 2004 at 12:20:58PM -0800, Stas Bekman wrote:

I completely agree with you, Hugo. But I'm also sure that you know that 
when something doesn't work under -T a frustrated user simply turns it off. 
So:

 Well yes it does, in an untainted environment

is really, not it doesn't work. I'd rather relax taint checking in certain 
places, rather than have the user turn it off completely. Certainly 
documenting the issue should be helpful.


Whether relxed tainting is superior to no tainting is surely dependent on your
view of tainting, to whit:
1) If tainting is a security measure to prevent malicious attackers (e.g., as
used in suid scripts), then a relaxed tainting provides a false sense of
security, and at least no tainting lets you know that the script is not to be
trusted.
2) If tainting is a bit like warnings, in that it's a helpful warning measure
to assist in catching a number of common issues but not a guarantee of
anything, then as you say, a relaxed taint that's used is better than none at
all.
Agreed for the general case. But it doesn't apply to this case. Because:

#!/usr/bin/perl -T
require Foo;
print $Foo::Version;
and

#!/usr/bin/perl -T
my $version = parse_version_untaint_source('Foo');
print $version;
are *exactly* the same from the security point of view, because require() 
ignores the tainting flag.

So if you *do* trust require() of a random file to acquire its version, you 
ought to trust parse_version_untaint_source() just the same.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: efficient module version checking without loading the module?

2004-03-25 Thread Ken Williams
On Mar 24, 2004, at 2:20 PM, Stas Bekman wrote:
That's said, it'd be great to see the perl test suite run all its 
tests under -T. I thought we have discussed this about a year ago or 
so.
I'm not sure that's a good idea.  Aren't there tests in the suite that 
invoke system-level operations on data that comes from outside the test 
scripts?

 -Ken



Re: efficient module version checking without loading the module?

2004-03-25 Thread Ken Williams
On Mar 25, 2004, at 2:31 PM, Stas Bekman wrote:
So if you *do* trust require() of a random file to acquire its 
version, you ought to trust parse_version_untaint_source() just the 
same.

It's not obvious to me that eval-ing an arbitrary (or semi-arbitrary) 
line of a file is always as safe as eval-ing the entire file.  Consider 
the following highly contrived example:

package FoolMeTwice;

my $string = 'EOF';
  $VERSION = 5;  system(rm -rf /);
EOF
$VERSION = 6;

__END__

That will do almost nothing with use FoolMeTwice;, but doing 
parse_version_untaint_source() will wreck your system.

Maybe there are no non-contrived examples, though.

 -Ken



Re: efficient module version checking without loading the module?

2004-03-25 Thread Stas Bekman
Ken Williams wrote:
On Mar 25, 2004, at 2:31 PM, Stas Bekman wrote:

So if you *do* trust require() of a random file to acquire its 
version, you ought to trust parse_version_untaint_source() just the same.

It's not obvious to me that eval-ing an arbitrary (or semi-arbitrary) 
line of a file is always as safe as eval-ing the entire file.  Consider 
the following highly contrived example:

package FoolMeTwice;

my $string = 'EOF';
  $VERSION = 5;  system(rm -rf /);
EOF
$VERSION = 6;

__END__

That will do almost nothing with use FoolMeTwice;, but doing 
parse_version_untaint_source() will wreck your system.

Maybe there are no non-contrived examples, though.
OK, I stand corrected. Thanks Ken.

In which case using laundering and eval'ing in the Safe compartment is 
probably the best idea. Though if I remember correctly Safe has lots of 
problems (doesn't quite work in certain environments), so I'm not sure how 
practical it is.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: efficient module version checking without loading the module?

2004-03-25 Thread Stas Bekman
David Nicol wrote:


Stas Bekman wrote:

In which case using laundering and eval'ing in the Safe compartment is 
probably the best idea. Though if I remember correctly Safe has lots 
of problems (doesn't quite work in certain environments), so I'm not 
sure how practical it is.


What's the advantage of that over opening the file for reading
and looking for /\$VERSION\s*=\s*([^\s\;]+)/ in it?
(adjust the regex some to handle quoting if needed)
If it was that simple do you think MM::parse_version wouldn't have done just 
that. Unfortunately it's not.

Adjusting the version search regex to handle problems such as the
version is deswcribed on multiple lines, or the version is described
within quotes -- workarounds are possible, but it seems like
documenting that that is what your version checker does and doing it
instead of trying to compensate for all edge cases would be a reasonable
approach.
That's is what documented:

http://pause.perl.org/pause/query?ACTION=pause_04about

Other conventions you should know about
[...]
Please make sure all your *.pm files contain a $VERSION variable that conforms 
to the CPAN rules, i.e. the complete computation of $VERSION must take place 
on the one first line within the module that assigns to it. You can test if 
this is the case by running

perl -MExtUtils::MakeMaker -le 'print MM-parse_version(shift)' 'file'

on the filenames in question. The CPAN indexer will run this code within a 
Safe compartement, so maybe even if the above command succeeds, PAUSE may fail 
if you're doing file IO or other potentially dangerous things within that line.


As usual, i might not know what I'm talking about.



--
__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: efficient module version checking without loading the module?

2004-03-24 Thread hv
Stas Bekman [EMAIL PROTECTED] wrote:
:Unfortunately ExtUtils::MM_Unix-parse_version is unusable, because it doesn't 
:work under -T :( That leaves me no choice but to duplicate loads of code :(
[...]
:Here is the fix against blead perl:
:--- lib/ExtUtils/MM_Unix.pm.orig2004-03-23 12:06:37.153572807 -0800
:+++ lib/ExtUtils/MM_Unix.pm 2004-03-23 17:27:25.849684620 -0800
:@@ -3092,6 +3092,8 @@
: next if $inpod || /^\s*#/;
: chop;
: next unless /(?!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
:+# untaint
:+{ local($1, $2); ($_ = $_) = /(.*)/; }
: my $eval = qq{
: package ExtUtils::MakeMaker::_version;
: no strict;

Hmm, so we read some text from an arbitrary file, then eval a selected
line from that (after wrapping it up some). Making that work under -T
simply by treating all possible strings as safe seems like a bad idea -
I think the existing behaviour is probably more correct, unless you are
going to provide a regexp that'll match only guaranteed-safe code
fragments.

If your particular -T script knows when parse_version is being called,
and upon what files, and has already taken separate steps to determine
that these files should be trusted, then that's fine. But to modify
parse_version in a way that assumes the caller has done that seems
inappropriate to me - for your case I think it would be more reasonable
to duplicate the function to make a parse_version_from_trusted_file().
Whether such an additional function would also be suitable for inclusion
in ExtUtils::* I don't know.

Hugo


Re: efficient module version checking without loading the module?

2004-03-23 Thread Stas Bekman
Stas Bekman wrote:
Rafael Garcia-Suarez wrote:

Stas Bekman wrote in perl.perl5.porters :

I'm facing a problem where loading a module in order to test its
version, is unapplicable. When a certain module/version is required
it's ok to load the module and die if the version is not
satisfactory.


You can use ExtUtils::MM_Unix-parse_version($pmfile).


Thanks Rafael, but you end up with an ugly code like:

for my $path (@INC) {
my $pmfile = $path/$file;
next unless -e $pmfile;
ExtUtils::MM_Unix-parse_version($pmfile);
}
It sounds like an opportunity for a core API to encapsulate this 
functionality. e.g. VERSION_NO_LOAD?
Unfortunately ExtUtils::MM_Unix-parse_version is unusable, because it doesn't 
work under -T :( That leaves me no choice but to duplicate loads of code :(

#!/usr/bin/perl-blead-ithread -wlT
require ExtUtils::MM_Unix;
my $file = CGI.pm;
for my $path (@INC) {
my $pmfile = $path/$file;
next unless -e $pmfile;
print ExtUtils::MM_Unix-parse_version($pmfile);
last;
}
gives:

Insecure dependency in eval while running with -T switch at 
/usr/lib/perl5/5.8.3/ExtUtils/MM_Unix.pm line 3123, FH line 22.

Here is the fix against blead perl:

--- lib/ExtUtils/MM_Unix.pm.orig2004-03-23 12:06:37.153572807 -0800
+++ lib/ExtUtils/MM_Unix.pm 2004-03-23 17:27:25.849684620 -0800
@@ -3092,6 +3092,8 @@
next if $inpod || /^\s*#/;
chop;
next unless /(?!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
+# untaint
+{ local($1, $2); ($_ = $_) = /(.*)/; }
my $eval = qq{
package ExtUtils::MakeMaker::_version;
no strict;
most likely it won't apply because of the bloody tabs, so I've attached it as 
well for your convenience.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com
--- lib/ExtUtils/MM_Unix.pm.orig	2004-03-23 12:06:37.153572807 -0800
+++ lib/ExtUtils/MM_Unix.pm	2004-03-23 17:27:25.849684620 -0800
@@ -3092,6 +3092,8 @@
 	next if $inpod || /^\s*#/;
 	chop;
 	next unless /(?!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
+# untaint
+{ local($1, $2); ($_ = $_) = /(.*)/; }
 	my $eval = qq{
 	package ExtUtils::MakeMaker::_version;
 	no strict;


Re: efficient module version checking without loading the module?

2004-03-23 Thread Stas Bekman
[EMAIL PROTECTED] wrote:
Stas Bekman [EMAIL PROTECTED] wrote:
:Unfortunately ExtUtils::MM_Unix-parse_version is unusable, because it doesn't 
:work under -T :( That leaves me no choice but to duplicate loads of code :(
[...]
:Here is the fix against blead perl:
:--- lib/ExtUtils/MM_Unix.pm.orig2004-03-23 12:06:37.153572807 -0800
:+++ lib/ExtUtils/MM_Unix.pm 2004-03-23 17:27:25.849684620 -0800
:@@ -3092,6 +3092,8 @@
: next if $inpod || /^\s*#/;
: chop;
: next unless /(?!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
:+# untaint
:+{ local($1, $2); ($_ = $_) = /(.*)/; }
: my $eval = qq{
: package ExtUtils::MakeMaker::_version;
: no strict;

Hmm, so we read some text from an arbitrary file, then eval a selected
line from that (after wrapping it up some). Making that work under -T
simply by treating all possible strings as safe seems like a bad idea -
I think the existing behaviour is probably more correct, unless you are
going to provide a regexp that'll match only guaranteed-safe code
fragments.
If your particular -T script knows when parse_version is being called,
and upon what files, and has already taken separate steps to determine
that these files should be trusted, then that's fine. But to modify
parse_version in a way that assumes the caller has done that seems
inappropriate to me - for your case I think it would be more reasonable
to duplicate the function to make a parse_version_from_trusted_file().
Whether such an additional function would also be suitable for inclusion
in ExtUtils::* I don't know.
May be you are right, Hugo, in which case perl provides no function to figure 
a version number without first loading the module. Besides, no module that 
ever wants to run under -T environment can use 
ExtUtils::MM_Unix-parse_version, because it will break. If you have an 
alternative solution, please suggest it.

Besides, If you are going to say:

require Foo;

doesn't it make Foo trusted enough to make contents of Foo.pm trusted for eval 
STRING?



__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: efficient module version checking without loading the module?

2004-03-23 Thread Stas Bekman
John Peacock wrote:
Stas Bekman wrote:

May be you are right, Hugo, in which case perl provides no function to 
figure a version number without first loading the module. Besides, no 
module that ever wants to run under -T environment can use 
ExtUtils::MM_Unix-parse_version, because it will break. If you have 
an alternative solution, please suggest it.


If you don't mind the extra dependency, it should be possible to add 
this to the CPAN version module (and thence to the core in 5.9.x).  I 
just need a name for the new function (I don't like parse_version that 
much).
That makes sense, John. I'm not sure what's the best name. 
no_load_parse_version? module2version?

As a side note ExtUtils::MM's functions should have never left the scope of 
EU::MM internals. e.g. people suggest to use ExtUtils::MakeMaker::find_perl 
because it's the only function shipped in the core that gives you more or less 
correct path to perl, but no one cares that it loads heaps of modules and runs 
tons of code to achieve a simple goal that perl core should have provided the 
method for in first place (i.e. $X is not suitable for running an external 
process on many platforms, nor $Config{perlpath} ).

Besides, If you are going to say:

require Foo;

doesn't it make Foo trusted enough to make contents of Foo.pm trusted 
for eval STRING?
That seems reasonable...
I thought so ;)

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com