[25858] in Perl-Users-Digest
Perl-Users Digest, Issue: 8093 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed May 18 18:05:41 2005
Date: Wed, 18 May 2005 15:05:05 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Wed, 18 May 2005 Volume: 10 Number: 8093
Today's topics:
Re: Alternatives to Safe.pm (not full of security holes <ignoramus22906@NOSPAM.22906.invalid>
Re: Alternatives to Safe.pm (not full of security holes <mikeh@perusion.net>
Re: Clean out accents in French names <pln@cosmic.stanford.edu>
getting IP address of remote host from socket (stdin) <news@mutare.noc.clara.net>
Re: getting IP address of remote host from socket (stdi (Anno Siegel)
Re: Perl generated navigation menu <joe@inwap.com>
Re: test if statement from database xhoster@gmail.com
Re: test if statement from database <efbo@hotmail.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 18 May 2005 20:45:07 GMT
From: Ignoramus22906 <ignoramus22906@NOSPAM.22906.invalid>
Subject: Re: Alternatives to Safe.pm (not full of security holes)?
Message-Id: <d6g9gj$oug$0@pita.alt.net>
On Tue, 17 May 2005 04:58:21 -0000, Mike Heins <mikeh@perusion.net> wrote:
> On 2005-05-13, Ignoramus18353 <ignoramus18353@NOSPAM.18353.invalid> wrote:
>> On Thu, 12 May 2005 21:39:35 -0000, Mike Heins <mikeh@perusion.net> wrote:
>>> On 2005-05-12, Ignoramus18353 <ignoramus18353@NOSPAM.18353.invalid> wrote:
>>>> On Thu, 12 May 2005 19:32:23 -0000, Mike Heins <mikeh@perusion.net> wrote:
>>>>> On 2005-05-12, Ignoramus18353 <ignoramus18353@NOSPAM.18353.invalid> wrote:
>>>>>> On 12 May 2005 16:36:32 GMT, Christopher Nehren <apeiron+usenet@coitusmentis.info> wrote:
>>>>>>> On 2005-05-12, Ignoramus18353 scribbled these
>>>>>>> curious markings:
>>>>>>>> I first chose Safe.pm to run user submitted code in a safe
>>>>>>>> compartment. Now I realize that Safe.pm is so full of holes that it
>>>>>>>> is not funny.
>>>>>>>
>>>>>>> How about, instead of just whining about a situation that (considering
>>>>>>> the popularity of Safe) is extremely serious and doing *absolutely
>>>>>>> nothing* about it, you submit bug reports of these holes to the author
>>>>>>> so that they can be fixed so that you *can* use it?
>>>>>>
>>>>>> I did not discover these bugs, I read about them from various bug list
>>>>>> archives. So they are all already known. Safe.pm is no longer
>>>>>> supported by its author due to all the holes. My understanding is that
>>>>>> it basically cannot be made to work right.
>>>>>>
>>>>>> I am interested in real solutions. I am not a perl security expert and
>>>>>> I cannot expect to know all potential holes in safe.pm.
>>>>>>
>>>>>
>>>>> I would like to know about any *existing* holes. Are you sure you
>>>>> aren't reading material from years ago?
>>>>
>>>> I refer you to
>>>>
>>>> http://www.codecomments.com/archive233-2004-5-187827.html
>>>>
>>>> and this exploit:
>>>>
>>>> sub forbidden { print "forbidden\n"; }
>>>>
>>>> my $eval = '@{my $x="main::forbidden"; $x=\&$x; $x->(); []}';
>>>>
>>>> my $output = $s->reval("sub{qq\0$eval\0}", 1);
>>>> die $@ if $@;
>>>> $output->(); # calls &main::forbidden
>>>>
>>>> Basically, you define sub forbidden in the main namespace, and you can
>>>> call it from your perl code inside the Safe compartment by doing this:
>>>>
>>>> @{my $x="main::forbidden"; $x=\&$x; $x->(); []}
>>>>
>>>> I tried it myself, unfortunately, it still breaches security, with the
>>>> latest Safe.pm and all. I was extremely upset, as I already wrote all
>>>> code using Safe.pm and liked what I had.
>>>>
>>>
>>> The routine *compiles* under Safe, it doesn't execute there. Have you tried
>>> running it in a compartment?
>>
>> Yep, forbidden is defined way outside the compartment, and yet it
>> executes from the compartment, contrary to my intent. I ran the code and
>> saw the output.
>
> Apparently you don't understand.
Possibly.
>> sub forbidden { print "forbidden\n"; }
>
> This sub is indeed outside the compartment.
>
>> my $eval = '@{my $x="main::forbidden"; $x=\&$x; $x->(); []}';
>
>> my $output = $s->reval("sub{qq\0$eval\0}", 1);
>
> Here you compile a subroutine and get a reference.
>
>
>> die $@ if $@;
>> $output->(); # calls &main::forbidden
>
> Now you run this routine outside of Safe. Why would you think Safe
> would protect you there?
>
I was hoping that Safe would protect me from obtaining a reference to
a subroutine. In any case, apparently you are explaining what is
happening, rather well.
The reason why I did what I did -- obtained a reference to a
subroutine and then executed it -- was to allow myself to run trusted
outside code from inside Safe.
I allow code inside the compartment to call a few subroutines that I
provide via Safe::Hole. They are needed to make my system work as
intended. Only subroutines that I allow, are supposed to be permitted.
This seemed to work okay in the sense of not allowing to call anything
else explicitly. It did, however, permit a secudity hole that I
described (and that could be described as one of my own making).
If I ran untrusted code without obtaining a subref from code, and
instead by executing it directly in the Safe compartment, then that
code somehow would not permit Safe to execute any outside functions
that I supplied, due to a "require violates opcode" error of some sort.
i
------------------------------
Date: Wed, 18 May 2005 21:59:05 -0000
From: Mike Heins <mikeh@perusion.net>
Subject: Re: Alternatives to Safe.pm (not full of security holes)?
Message-Id: <slrnd8nel8.qes.mikeh@bill.heins.net>
On 2005-05-18, Ignoramus22906 <ignoramus22906@NOSPAM.22906.invalid> wrote:
>>>> The routine *compiles* under Safe, it doesn't execute there. Have you tried
>>>> running it in a compartment?
>>>
>>> Yep, forbidden is defined way outside the compartment, and yet it
>>> executes from the compartment, contrary to my intent. I ran the code and
>>> saw the output.
>>
>> Apparently you don't understand.
>
> Possibly.
>
>>> sub forbidden { print "forbidden\n"; }
>>
>> This sub is indeed outside the compartment.
>>
>>> my $eval = '@{my $x="main::forbidden"; $x=\&$x; $x->(); []}';
>>
>>> my $output = $s->reval("sub{qq\0$eval\0}", 1);
>>
>> Here you compile a subroutine and get a reference.
>>
>>
>>> die $@ if $@;
>>> $output->(); # calls &main::forbidden
>>
>> Now you run this routine outside of Safe. Why would you think Safe
>> would protect you there?
>>
>
> I was hoping that Safe would protect me from obtaining a reference to
> a subroutine. In any case, apparently you are explaining what is
> happening, rather well.
>
> The reason why I did what I did -- obtained a reference to a
> subroutine and then executed it -- was to allow myself to run trusted
> outside code from inside Safe.
That is the whole point -- you define the subroutine outside
of Safe, then "share" it to Safe. Then you run the code with $safe->reval()
or $safe->rdo() and it protects you.
>
> I allow code inside the compartment to call a few subroutines that I
> provide via Safe::Hole. They are needed to make my system work as
> intended. Only subroutines that I allow, are supposed to be permitted.
I do this all the time. It works well when the modules you use are
well-written.
>
> This seemed to work okay in the sense of not allowing to call anything
> else explicitly. It did, however, permit a secudity hole that I
> described (and that could be described as one of my own making).
It is not a security hole, since you are running the code outside
of Safe.
>
> If I ran untrusted code without obtaining a subref from code, and
> instead by executing it directly in the Safe compartment, then that
> code somehow would not permit Safe to execute any outside functions
> that I supplied, due to a "require violates opcode" error of some sort.
You can't do runtime requires within Safe without completely opening
the kimono. What you have to do is "use" the modules prior to execution
and avoid runtime calls to require().
In my opinion, runtime require statements should be forbidden in
module methods and functions that are not part of initialization.
--
Mike Heins
Perusion -- Expert Interchange Consulting http://www.perusion.com/
Be patient. God isn't finished with me yet. -- unknown
------------------------------
Date: Wed, 18 May 2005 19:15:25 +0000 (UTC)
From: "Patrick L. Nolan" <pln@cosmic.stanford.edu>
Subject: Re: Clean out accents in French names
Message-Id: <d6g48d$ofm$1@news.Stanford.EDU>
John Bokma <john@castleamber.com> wrote:
> Patrick L. Nolan wrote:
>> I have a script that takes information, including people's
>> names, and builds an XML file. I just found that the
>> application that reads the XML is fussy about characters.
> Then use something like:
> <?xml version="1.0" encoding="ISO-8859-1"?>
> ^^^^^^^^^^
>> Has this problem been solved?
> Specify an encoding, and there shouldn't be any problem.
Thanks. That works. I'm a bit surprised that it was that
simple. I got the XML format by reverse-engineering files
that were produced by the target application. Since they
didn't have an encoding specified, I thought they wouldn't
be able to deal with it. They must be using a standard
XML parser library.
--
* Patrick L. Nolan *
* W. W. Hansen Experimental Physics Laboratory (HEPL) *
* Stanford University *
------------------------------
Date: Wed, 18 May 2005 20:42:50 +0100
From: Ollie Cook <news@mutare.noc.clara.net>
Subject: getting IP address of remote host from socket (stdin)
Message-Id: <slrnd8n6lp.13t1.news@mutare.noc.clara.net>
Ordinarily I would use the getpeername and getsockname functions to get
the IP address associated with each end of a socket. However, this
appears not to work for a script which is started from xinetd[1].
xinetd connects the socket over which the connection arrives to stdin
and stdout of the spawned process so when you read from standard input
you are in fact reading from the network.
In a C application started in this way, you can retrieve the IP
addresses associated with the 'socket' as follows (pseudocode only):
getpeername(fileno(stdin), (struct sockaddr *) &sa, &sz);
inet_ntoa(sa.sin_addr);
even though 'stdin' isn't a real socket.
However, doing a similar thing in Perl:
$sockaddr = getpeername(fileno(STDIN)); # 0
($port, $addr) = sockaddr_in($sockaddr);
gives the following error:
getpeername() on unopened socket 0 at proxy.pl line 258.
Use of uninitialized value in subroutine entry at
/usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16
at /usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
Does anyone have any advice on how I might be able to get the IPs
associated with a socket, when that socket is in fact STDIN/STDOUT as
presented by xinetd? I am using Perl 5.6.1.
Any help would be greatly appreciated.
Ollie
1: www.xinetd.org
------------------------------
Date: 18 May 2005 21:27:59 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: getting IP address of remote host from socket (stdin)
Message-Id: <d6gc0v$a58$1@mamenchi.zrz.TU-Berlin.DE>
Ollie Cook <news@mutare.noc.clara.net> wrote in comp.lang.perl.misc:
> Ordinarily I would use the getpeername and getsockname functions to get
> the IP address associated with each end of a socket. However, this
> appears not to work for a script which is started from xinetd[1].
>
> xinetd connects the socket over which the connection arrives to stdin
> and stdout of the spawned process so when you read from standard input
> you are in fact reading from the network.
[...]
> $sockaddr = getpeername(fileno(STDIN)); # 0
> ($port, $addr) = sockaddr_in($sockaddr);
>
> gives the following error:
>
> getpeername() on unopened socket 0 at proxy.pl line 258.
>
> Use of uninitialized value in subroutine entry at
> /usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
> Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16
> at /usr/local/lib/perl5/5.6.1/mach/Socket.pm line 312.
Try this:
use IO::Socket::INET;
my $sock = IO::Socket::INET->new;
$sock->fdopen( fileno STDIN, 'r') or die "dup: $!";
my $peerhost = $sock->peerhost or die "peerhost: $!";
print "peerhost is $peerhost\n";
This works for me in a similar situation, though I can't be sure how
exactly inetd establishes the pipeline.
Anno
------------------------------
Date: Wed, 18 May 2005 13:56:02 -0700
From: Joe Smith <joe@inwap.com>
Subject: Re: Perl generated navigation menu
Message-Id: <ctydneoIjex4NhbfRVn-vA@comcast.com>
michael wrote:
>>accessing a URL, it is the case of creating a file that will
>>become the target of a URL.
>
> Sounds right too. I found that $ENV{"DOCUMENT_NAME"} does what I need.
No, DOCUMENT_NAME is only present in the CGI environment. What you
are writing is not a CGI so $ENV{DOCUMENT_NAME} will not be set.
Do you understand what I'm saying? It is important to know the
difference between programs what create HTML files and CGI scripts.
0. Write a perl script to generate HTML files off-line.
1. Update the data file that the perl script uses.
2. Run the perl script to create a bunch of *.html files.
3. Use FTP or other upload procedure to copy the html files
to the web server.
4. Verify that the changes are visible on the server by using a browser.
Repeat steps 2 through 4 whenever step 1 is performed, which may be
once a week, but definitely not thousands of times per day.
There are valid reasons for using CGI to generate results on the
fly, but the task, as you have stated it, does not require CGI.
-Joe
------------------------------
Date: 18 May 2005 18:09:02 GMT
From: xhoster@gmail.com
Subject: Re: test if statement from database
Message-Id: <20050518140902.496$Fq@newsreader.com>
"A. Sinan Unur" <1usa@llenroc.ude.invalid> wrote:
> xhoster@gmail.com wrote in news:20050518134749.474$9x@newsreader.com:
>
> > ef <efbo@hotmail.com> wrote:
>
> >> I have an compare statement stored in the database. e.g. 'fieldx >
> >> 10'. I read that and want to use that directly in a perl statement,
> >> something like
> >>
> >> $iffromdatabase =~ s/fieldx/realvalueoffieldx/;
> >> if ( /$iffromdatabase/e ){
> >> .....
> >> }
> ...
> > You could probably do this with eval, but you would probably be better
> > off doing something like:
> >
> > my ($field,$op,$constant) = $fromdb =~ /$(.*) (>) (.*)$/ or die;
>
> Based on apply_logic below, this should probably be (untested):
>
> my ($field,$op,$constant) = $fromdb =~ /$(.*) (<|=|>) (.*)$/ or die;
Yes, and also the first $ in the regex should be ^.
(But still untested).
Come to think of it, just
my ($field,$op,$constant)= split ' ', $fromdb;
might be better, as then the operator only needs be validated in
apply_logic rather than in two places. Provided of course that
white space is appropriate as a delimiter.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
------------------------------
Date: 18 May 2005 21:27:59 GMT
From: ef <efbo@hotmail.com>
Subject: Re: test if statement from database
Message-Id: <Xns965AECD068B4Cefbo@195.121.6.84>
Thanks for the suggestions, i will test it.
Bo.
xhoster@gmail.com wrote in news:20050518140902.496$Fq@newsreader.com:
> "A. Sinan Unur" <1usa@llenroc.ude.invalid> wrote:
>> xhoster@gmail.com wrote in news:20050518134749.474$9x@newsreader.com:
>>
>> > ef <efbo@hotmail.com> wrote:
>>
>> >> I have an compare statement stored in the database. e.g. 'fieldx >
>> >> 10'. I read that and want to use that directly in a perl statement,
>> >> something like
>> >>
>> >> $iffromdatabase =~ s/fieldx/realvalueoffieldx/;
>> >> if ( /$iffromdatabase/e ){
>> >> .....
>> >> }
>> ...
>> > You could probably do this with eval, but you would probably be better
>> > off doing something like:
>> >
>> > my ($field,$op,$constant) = $fromdb =~ /$(.*) (>) (.*)$/ or die;
>>
>> Based on apply_logic below, this should probably be (untested):
>>
>> my ($field,$op,$constant) = $fromdb =~ /$(.*) (<|=|>) (.*)$/ or die;
>
> Yes, and also the first $ in the regex should be ^.
> (But still untested).
>
>
> Come to think of it, just
> my ($field,$op,$constant)= split ' ', $fromdb;
> might be better, as then the operator only needs be validated in
> apply_logic rather than in two places. Provided of course that
> white space is appropriate as a delimiter.
>
>
> Xho
>
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 8093
***************************************