Re: untainting PATH in mod_perl

2003-07-11 Thread Dominique Quatravaux
   Sorry, getting out of good ideas.. 

  Surprise, surprise: I found out that my code does not work under
mod_perl 1.23 either! And I found the real solution: one has to add

  PerlSetupEnv Off

to the Apache configuration file. Now the untainting mumbo-jumbo in
perl section works.

  Warning: this has the consequence of breaking the part of the CGI
environment emulation that deals with environment (e.g. instead of
$ENV{HTTP_USER_AGENT}, you now have to check
Apache-request()-subprocess_env(HTTP_USER_AGENT)). Glancing at its
source code, I don't think CGI.pm will survive that...

  BTW, I finally got around to reading mod_perl's source, and it
is now clear to me that the environment, when being copied from
-subprocess_env() into %ENV, gets tainted (around line 704 in
src/modules/perl/mod_perl.c). The whole %ENV gets tainted, not just
the HTTP_USER_AGENT and such from the CGI context, so PATH is tainted
as well. This explains our now common problem - and also guarantees
that there is no easy way out of it if you use CGI.pm yourself :-(.

  Hope I'm being helpful at last,

-- 
Dominique QUATRAVAUX   Ingénieur senior
01 44 42 00 08 IDEALX




Re: untainting PATH in mod_perl

2003-07-10 Thread Dominique Quatravaux
 I need some help with this. Can you share the code you use w/in
 your Perl section?

  Sure! Here is how I untaint a selected range of variables from the
WWW server's %ENV, and discard all the others (good move to ease
debugging anyway):

   # From httpd.conf
   PerlTaintCheck On
   
   perl
  BEGIN {
   # Untaint environment. Those variables come from
   # Apache; even if they didn't, they would come from the root
   # user who launched Apache. No security problems here.
   
   my %cleanenv;
   foreach my $var (qw(PATH GATEWAY_INTERFACE MOD_PERL)) {
  ($cleanenv{$var})=($ENV{$var} =~ m/^(.*)$/g);
   }
   %ENV=%cleanenv;
   }   
   /perl

 I'm pretty confused because I was able to untaint my PATH var.
 by putting 
 
 $ENV{PATH} = '/bin';
 
 in the ***same scope*** where I was getting the error.

 Makes sense to me: if you are using Apache::Registry (for example),
your script only gets compiled once and the BEGIN blocks run at that
time. In fact Apache::Registry reads your cgi, then cooks it into
something like this:

package Some::Name::Made::Up::By::Apache::Registry::To::Isolate::Your::cgi;

sub handler {
  # Your script here
}

  Then it evals that (by that time, the BEGIN blocks run), then calls
Some::Name::...::handler(). The purpose of these steps is caching: the
next time the CGI is hit, the evalling needs not be redone, only the
handler call.

  Now, my guess was that %ENV gets reset between the eval and the
handler call. As you mention, putting the untainter in the same scope
solves the problem, because you now circumvent the cleaning. Putting
it in the perl section should also solve the problem once for all,
because the perl section runs before the default %ENV value is
stashed (even before Apache forks, in fact).

-- 
Dominique QUATRAVAUX   Ingénieur senior
01 44 42 00 08 IDEALX




Re: untainting PATH in mod_perl

2003-07-10 Thread Dominique Quatravaux
 Thanks for sharing your code; unfortunately, it's not working for me.
 I copied it into my httpd.conf file, stopped/started the server and
 I still get the same error:

  Sorry, getting out of good ideas.. I'm not using mod_perl 1.99, this
probably explains why my code does not work, and also it prevents me
from further investigating your problem. There was a thread recently
on the list about perl ... /perl section only being implemented
recently, do you run the latest version of mod_perl?

 Insecure $ENV{PATH} while running setgid

  While running setgid? That's odd (although I don't think this
nterfers with your problem in any way)

 foreach my $release (`/bin/ls $path`) { # $path is already untainted
  do stuff
 }

  TI (still) MTOWTDI: why not try

  use IO::Pipe;
  my $pipe = new IO::Pipe()-reader(/bin/ls,$path);

  while($pipe) {
  }

  (although this will not save you from having to review all your codebase)

-- 
Dominique QUATRAVAUX   Ingénieur senior
01 44 42 00 08 IDEALX




Re: untainting PATH in mod_perl

2003-07-09 Thread Dominique Quatravaux
 In plain CGI, I normally do this inside a BEGIN 
 block; in mod_perl however, this doesn't work.

This would work if this was done in a Perl section of the httpd.conf
file (this is what I do). I am not sure why the BEGIN block is not
executed, but my guess is that the environment gets automatically
restored at the end of every script run under Apache::Registry,
including the tainted PATH.

-- 
Dominique QUATRAVAUX   Ingénieur senior
01 44 42 00 08 IDEALX




Re: Single login/sign-on for different web apps?

2002-01-17 Thread Dominique Quatravaux

 I hadn't really taken a look at personal certificates until this thread
 came up.  It looks like thawte is offering personal certificates at no
 charge.
 
 http://www.thawte.com/getinfo/products/personal/contents.html

  Yep, and the society I work in develops a GPLed PKI, which is a
Perl+PHP+LDAP app for rolling your own certificates (both user and
server):

   http://idx-pki.idealx.com/

  Certificates are indeed a straightforward way of getting SSO - but
you have to carry your certificate with you whenever you change
workstations. Here are reasonable solutions (trading security for
convenience):
  * most secure: use USB crypto tokens (slow and extra per-user price,
but will safeguard the private key and destroy it upon attack);
  * very secure: use dedicated workstations, one per user
   (impractical), or laptops (expensive but may be amortized with
   other needs); 
  * not so secure (equivalent of password SSO): carry the key on a
floppy, and keep it password-encrypted at all times.

  On the server side, you have to get your Apache to grok certificates
(easy with recent versions of openssl), and the authentication info
then gets passed down to PHP and Perl scripts as environment variables
(OK, this guy is called CN=John Doe, OU=sales, O=yourcompany - trust
me on this). You have to patch your apps, sure, but all the burden of
binding a bunch of crypto bits to a name is removed from you in a
highly secure fashion.

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: RFC: Exception::Handler

2002-01-14 Thread Dominique Quatravaux

 One of the things I don't like about traditional try/catch handling is
 that it doesn't allow for class level programming.  You need to allow
 any subroutine to try/catch exceptions (die).  It's also nice to
 notify any object in the stack that there is an unhandled exception
 passing through its code.

  I'm afraid I don't get it - isn't it what the finally functionality
in Error.pm (CPAN) does ?

  try {
stuffThatMayThrow();
  } finally {
releaseResources();
  };


  This eliminates a lot of explicit
 try/catches.

  Well, destructors are of some help too in that issue.

 (not lighting up a flamewar, just trying to understand the issues - I
don't know much about Aspects, but I find exception handling with
Error.pm a breeze, even for big projects)

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: Can't pipe to external programs

2001-11-07 Thread Dominique Quatravaux

 Hey list,
 
 We're trying to turn some xml into a pdf using fop. A wrapper has been
 written for fop so that we can pass it xml on the stdin, and get the
 pdf from the stdout.
 
 We're using IPC::Open2 to set this up:

  I remember having lots of trouble with the implicit redirection
that mod_perl performs (IIRC, STD[IN|OUT|ERR] streams don't map to file
descriptors 0, 1 and 2 under mod_perl and this confuses IPC::Open[23]).

  I ended up recoding my very own fork() - pipe() - dup() - exec()
- exit() stuff, using POSIX::close(), POSIX::dup2() (that don't get
confused) and POSIX::SYS_exit() instead of exit() in the child process
(so that global variables representing e.g. a database connection
don't get destroyed, causing shutdown messages to get sent to the
remote server).

 use IPC::Open2;
 open2(*README, *WRITEME, $progname);
 print WRITEME $thexml or warn problem writing to $progname: $!\n;
 my $pdf = README;
 close(WRITEME);
 close(README);

  You should close WRITEME before attempting to read, or deadlock may
occur because either 1) WRITEME wasn't flushed from Perl's stdio buffers
and $progname didn't see any input yet, or 2) $progname doesn't see
end-of-file and thus expects more data.

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: Are global variables truly global?

2001-11-05 Thread Dominique Quatravaux

 I have some state data that I need to persist between requests. At the
 moment these are COM objects, but they'll be ported to Perl Classes. It
 is quite important that only one of these instances exist per web
 server. These instances are too large to write and read to file on every
 request. So I have defined the variable as a package level variable.

  Package level variables are shared upon fork(), in the sense that
the memory segment(s) they use is made available to all child
processes. BUT the memory itself isn't shared, and any subsequent
write to the variable in one of the children will not reflect in the
others. So unless your state data is a constant, this is not what you want.

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: Mod_perl component based architecture

2001-10-16 Thread Dominique Quatravaux

 also does modperl support object oriented programming?

  Well yes it does indeed (see any good book on Perl, such as
«advanced Perl programming» from O'Reilly).

  As for the remaining of the question, I've been wondering for myself if
there is a MVC (model-view-controller) framework for WWW publishing in
Perl ? I gather there exist quite a few for Java, but I couldn't find
anything significant under Perl.

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: startup.pl for configuration

2001-07-25 Thread Dominique Quatravaux

  Hello,

 I would like to have a config file like /etc/mywebapp.conf where I would
 put all my modules configuration.

  Yep, that's what we do too.

  Then I would have a WebApp::LoadConfig
 module that would run from startup.pl, and initialize my Perl modules
 default variables at Apache start.

  I'd rather think of it as a WebApp::Config _object class_ than a
WebApp::LoadConfig _module_ (see below).

 My config file would be some like :
 
 ### /etc/mywebapp.conf
 ###
 ###
 MyPackageOne::Default_Value_One = 1
 MyPackageOne::Default_Value_One = 2

How about the Config::Ini module from CPAN, that implements m/Win...s/
.INI format ? It's versatile and quite easy to understand even for
your newbie users. Plus it's already done and well tested, and it has
write support (comments are discarded). Here at IDEALX we use a
subclass that goes like this:

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

package My::Hierarchy::Config;

use strict;

use Config::Ini;

use vars qw(@ISA); @ISA=qw(Config::Ini);

# new My::Hierarchy::Config() called with no args returns a
# config opened on the default configuration file.
sub new {
my ($class,$filename)=@_;
return $class-SUPER::new($filename or '/etc/mywebapp.conf');
}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

And then in every script:

my $config=new My::Hierarchy::Config;

$config-get(['somesection','somekey']);


This allows for maximum flexibility: by adding code to
My::Hierarchy::Config, you can provide convenience functions to do
just about anything that suits your needs (e.g. there could be one to
export the whole config file to random variables in all packages).

 
 and my startup.pl would have :
 
 ### startup.pl
 WebApp::LoadConfig-run(/etc/mywebapp.conf)
 [...]
 Would this be a good idea ? What do you think about? does somebody
 already use it ?

Well, it depends. We find it quite useful to stay in the CGI context
for our scripts, since unit tests are much easier with CGI.pm's
debugging code. And for that reason, we choose not to specialize
mod_perl's environment more than it already is (e.g. $r et al.). We
put the above boilerplate in every script, perhaps wrapped in a
convenience function (e.g. ``use My::Hierarchy::CGI;''). But if you
intend to jump the gap and have a totally ad-hoc structure for your
Perl pages (e.g. you use HTML::Mason or something alike), then yes,
why not make $config a global variable accessible to all Perl WWW
pages ?

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



Re: [BUG] $r-subprocess_env() leaking to %ENV

2001-07-18 Thread Dominique Quatravaux


 Can't all these modules (your scripts, 

 The environment leak in my test case was just to make my point clear,
not a programmatic example of course

 mod_ssl, etc) just use the request object and/or Apache notes to
 communicate?  That's exactly what they're there for!

  I get it now: there is a kind of lost-update (actually, lost-delete)
problem because both mod_ssl and mod_perl try to write into the
environment, and cleanup in the wrong sequence (update 1-update
2-cleanup 1-cleanup 2). Thank you for helping me pointing it out.

 At least mod_perl can be told not to mess with the environment:
 
 Directory /my/modperl/webroot
   PerlSetupEnv Off
 /Directory

  Well sure, I even tried it but I use CGI.pm from Perl 5.6 and 

CGI.pm $meth=$ENV{'REQUEST_METHOD'} if defined($ENV{'REQUEST_METHOD'});
CGI.pm [...]
CGI.pm # If $meth is not of GET, POST or HEAD, assume we're being debugged 
offline.

  And there comes a funny message in my error log telling me
to enter name=value pairs on the standard input :-) 

  Your proposition, however righteous, means a lot of work for a lot
of people... Or perhaps Apache::Registry::handler should do some
tie()ing ? (yuck)

  In the meantime, I will be cutting the StdEnvVars off from mod_ssl
configuration. Thanks again !

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]



[BUG] $r-subprocess_env() leaking to %ENV

2001-07-17 Thread Dominique Quatravaux

Hello,

I found the following behaviour in mod_perl, which is clearly
unexpected: I use an Apache that can serve both mod_perl and PHP
pages. I run it -X ; first I request the URI for this scriptlet
(under mod_perl's Apache::Registry):

#!/usr/bin/perl
$ENV{LEAKING}=oops;

Then I visit a PHP page that contains just phpinfo() - the LEAKING
variable is passed to it, I can see it in the HTTP_ENV_VARS.

So far, so good - a remanent environment may not be what I want, but
it certainly is not a bug. It becomes worse with a module that sets
things in the CGI namespace ($r-subprocess_env()), such as mod_ssl :
if I request the Perl scriptlet through SSL, all variables in the
subprocess_env (HTTPS, SERVER_CERTIFICATE et al., that normally show
up as HTTP_SERVER_VARS in phpinfo()) are somehow promoted as
environment variables, and become remanent in the server process
environment as shown above (i.e. they now appear as HTTP_ENV_VARS for
subsequent requests). This seems to happen at the time the first (I
didn't test more) request to an Apache::Registry script is made in the
life of an httpd : requesting phpinfo() pages beforehand doesn't
show any spurious environment data, even through SSL.

Using a debugger shows (as expected from %ENV modifications) that the
real environment (char **__environ) is modified in both scenari, so
this is not due to a bug in PHP.

I ended up writing a cleanup handler that restores %ENV to what it was
at server startup time, and everything works fine now.

Platform: RH 7.1, mod_perl 1.24_01, Apache 1.3.19, PHP 4.0.4pl1.

Sorry I cannot investigate any further by myself, because I know next
to nothing in XS and mod_perl uses it heavily. I just saw that %ENV is
tied by C code, but I hear it is related to tainting and I don't see how
this could cause the observed behaviour.

-- 
 Tout n'y est pas parfait, mais on y honore certainement les jardiniers 

Dominique Quatravaux [EMAIL PROTECTED]