Thread: plperl Safe restrictions
It has just been brought to my attention that we are being very restrictive about what we allow to be done in trusted plperl. Basically we allow the :default and :base_math set of operations (run perldoc Opcode or see http://www.perldoc.com/perl5.8.0/lib/Opcode.html for details of what these mean). In particular, we do not allow calls to perl's builtin sort, which is unpleasant, and on reviewing the list it seems to me we could quite reasonably allow access to pack and unpack also. bless and sprintf are also likely candidates for inclusion - I have not finished reviewing the list, and would welcome advice from perl gurus on this. On the other side, I think we should exclude the :base_io set which is part of the :default set (we don't want trusted plperl writing to stdout, for example - all IO should be forbidden). I know changing this at this stage of the dev cycle is bad, but I think it ought to be done. Unless there are loud squawks I will submit a patch RSN. It should be very low risk - one or two lines. cheers andrew
On Thu, 14 Oct 2004, Andrew Dunstan wrote: > It has just been brought to my attention that we are being very > restrictive about what we allow to be done in trusted plperl. Basically > we allow the :default and :base_math set of operations (run perldoc > Opcode or see http://www.perldoc.com/perl5.8.0/lib/Opcode.html for > details of what these mean). In particular, we do not allow calls to > perl's builtin sort, which is unpleasant, and on reviewing the list it > seems to me we could quite reasonably allow access to pack and unpack > also. bless and sprintf are also likely candidates for inclusion - I > have not finished reviewing the list, and would welcome advice from perl > gurus on this. > > On the other side, I think we should exclude the :base_io set which is > part of the :default set (we don't want trusted plperl writing to > stdout, for example - all IO should be forbidden). That makes sense. Allowing "rand" would be nice too. Jon -- Jon Jensen End Point Corporation http://www.endpoint.com/ Software development with Interchange, Perl, PostgreSQL, Apache, Linux, ...
Jon Jensen wrote: >On Thu, 14 Oct 2004, Andrew Dunstan wrote: > > > >>It has just been brought to my attention that we are being very >>restrictive about what we allow to be done in trusted plperl. Basically >>we allow the :default and :base_math set of operations (run perldoc >>Opcode or see http://www.perldoc.com/perl5.8.0/lib/Opcode.html for >>details of what these mean). In particular, we do not allow calls to >>perl's builtin sort, which is unpleasant, and on reviewing the list it >>seems to me we could quite reasonably allow access to pack and unpack >>also. bless and sprintf are also likely candidates for inclusion - I >>have not finished reviewing the list, and would welcome advice from perl >>gurus on this. >> >>On the other side, I think we should exclude the :base_io set which is >>part of the :default set (we don't want trusted plperl writing to >>stdout, for example - all IO should be forbidden). >> >> > >That makes sense. Allowing "rand" would be nice too. > > > > You can now - it's part of :base_math. What we should do, however, is disallow is calling srand, since pg goes to quite a bit of trouble to seed the PRNG. cheers andrew
On 14. okt 2004, at 21:09, Andrew Dunstan wrote: > It has just been brought to my attention that we are being very > restrictive about what we allow to be done in trusted plperl. > Basically we allow the :default and :base_math set of operations (run > perldoc Opcode or see http://www.perldoc.com/perl5.8.0/lib/Opcode.html > for details of what these mean). In particular, we do not allow calls > to perl's builtin sort, which is unpleasant, and on reviewing the list > it seems to me we could quite reasonably allow access to pack and > unpack also. bless and sprintf are also likely candidates for > inclusion - I have not finished reviewing the list, and would welcome > advice from perl gurus on this. pack and unpack are unfortunately not safe. Very useful, but they allow write/read access to random memory. It's really a shame perl doesn't have a pragma to make them safe or have safe versions of them. Bless should be OK, unless sensitive objects are provided to the procedures. A postgres question I don't know the answer to is whether allowing the user to trigger a segfault is a security problem. If it isn't, several opcodes may probably be allowed, including sort and sprintf. If it is, well, you need only follow the perl5-porters list to know that there's banal perl structures are continuously being found that will segfault perl, some at compile time, other at runtime. > On the other side, I think we should exclude the :base_io set which is > part of the :default set (we don't want trusted plperl writing to > stdout, for example - all IO should be forbidden). Definitely out :) > I know changing this at this stage of the dev cycle is bad, but I > think it ought to be done. Unless there are loud squawks I will submit > a patch RSN. It should be very low risk - one or two lines. Take care what you open. Perl may be a fairly secure, but the complex implementation means that problematic corner cases are regularly found. d. -- David Helgason, Business Development et al., Over the Edge I/S (http://otee.dk) Direct line +45 2620 0663 Main line +45 3264 5049
On Thu, 14 Oct 2004, Andrew Dunstan wrote: > >That makes sense. Allowing "rand" would be nice too. > > You can now - it's part of :base_math. Oh, ok. I saw it's not included in :base_core despite being in :base_math, but didn't realize explicitly including :base_math would bring it back. > What we should do, however, is disallow is calling srand, since pg goes > to quite a bit of trouble to seed the PRNG. That sounds reasonable. Jon -- Jon Jensen End Point Corporation http://www.endpoint.com/ Software development with Interchange, Perl, PostgreSQL, Apache, Linux, ...
Andrew Dunstan <andrew@dunslane.net> writes: > You can now - it's part of :base_math. What we should do, however, is > disallow is calling srand, since pg goes to quite a bit of trouble to > seed the PRNG. But changing the PRNG seed within one backend is not a security issue. At least, we allow anyone to do "SET SEED" or call setseed, so I don't see any reason to disallow it in plperl. In general I'm pretty sure that no one has reviewed the list of restrictions carefully, so by all means send in a patch once you've done so. regards, tom lane
David Helgason <david@uti.is> writes: > A postgres question I don't know the answer to is whether allowing the > user to trigger a segfault is a security problem. It would not be cool for a trusted language to allow such things, that's for sure. You could debate back and forth about whether we ought to allow it and warn that some versions of Perl may have exploitable bugs, but I'd prefer to err on the side of conservatism. regards, tom lane
David Helgason wrote: > On 14. okt 2004, at 21:09, Andrew Dunstan wrote: > >> It has just been brought to my attention that we are being very >> restrictive about what we allow to be done in trusted plperl. >> Basically we allow the :default and :base_math set of operations (run >> perldoc Opcode or see >> http://www.perldoc.com/perl5.8.0/lib/Opcode.html for details of what >> these mean). In particular, we do not allow calls to perl's builtin >> sort, which is unpleasant, and on reviewing the list it seems to me >> we could quite reasonably allow access to pack and unpack also. bless >> and sprintf are also likely candidates for inclusion - I have not >> finished reviewing the list, and would welcome advice from perl gurus >> on this. > > > pack and unpack are unfortunately not safe. Very useful, but they > allow write/read access to random memory. It's really a shame perl > doesn't have a pragma to make them safe or have safe versions of them. > > Bless should be OK, unless sensitive objects are provided to the > procedures. > > A postgres question I don't know the answer to is whether allowing the > user to trigger a segfault is a security problem. If it isn't, several > opcodes may probably be allowed, including sort and sprintf. If it is, > well, you need only follow the perl5-porters list to know that there's > banal perl structures are continuously being found that will segfault > perl, some at compile time, other at runtime. OK, based on this and some further thought, I have prepared the attached patch which does the right thing, I think, both in terms of what we allow and what we don't. First, we tighten security by disallowing access to srand and IO functions on existing filehandles (other IO ops are already disallowed). The we relax the restrictions by allowing access to perl's sort, sprintf and time routines. I decided against pack/unpack based on the above, and also decided that I couldn't think of any case where bless would have any practical use - although that might change later. I'm trying to keep changes minimal here. I don't believe that "time" carries any significant security implications, and I think the dangers from "sort" and "sprintf" are not so great as to disallow them. They might cause a SEGV in a pathological case, but that doesn't give the user access to the machine - if they can login to postgres they can probably mount any number of DOS attacks anyway. To answer David's question, the man says this about trusted functions: "the TRUSTED flag should only be given for languages that do not allow access to database server internals or the file system". I think the changes I propose fit in with that statement. The patch also does some other inconsequential tidying of overlong lines, and removes some unnecessary ops in the unsafe case. These are basically cosmetic - the only significant part is replacing this: $PLContainer->permit(':base_math'); with this: $PLContainer->permit(qw[:base_math !:base_io !srand sort sprintf time]); I have tested and it appears to do the right thing, both for the things excluded and those included. cheers andrew Index: src/pl/plperl/plperl.c =================================================================== RCS file: /home/cvsmirror/pgsql/src/pl/plperl/plperl.c,v retrieving revision 1.54 diff -c -r1.54 plperl.c *** src/pl/plperl/plperl.c 7 Oct 2004 19:01:09 -0000 1.54 --- src/pl/plperl/plperl.c 15 Oct 2004 14:48:18 -0000 *************** *** 250,266 **** static char *safe_ok = "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" ! "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" ! "$PLContainer->share(qw[&elog &spi_exec_query &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" "sub ::mksafefunc { return $PLContainer->reval(qq[sub { $_[0] $_[1]}]); }" ; static char *safe_bad = "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" ! "$PLContainer->permit_only(':default');$PLContainer->permit(':base_math');" ! "$PLContainer->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %SHARED ]);" "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " ! "elog(ERROR,'trusted perl functions disabled - please upgrade perl Safe module to at least 2.09');}]); }" ; SV *res; --- 250,269 ---- static char *safe_ok = "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" ! "$PLContainer->permit_only(':default');" ! "$PLContainer->permit(qw[:base_math !:base_io !srand sort sprintf time]);" ! "$PLContainer->share(qw[&elog &spi_exec_query &DEBUG &LOG " ! "&INFO &NOTICE &WARNING &ERROR %SHARED ]);" "sub ::mksafefunc { return $PLContainer->reval(qq[sub { $_[0] $_[1]}]); }" ; static char *safe_bad = "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" ! "$PLContainer->permit_only(':default');" ! "$PLContainer->share(qw[&elog &ERROR ]);" "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " ! "elog(ERROR,'trusted perl functions disabled - " ! "please upgrade perl Safe module to at least 2.09');}]); }" ; SV *res;
Tom Lane wrote: >David Helgason <david@uti.is> writes: > > >>A postgres question I don't know the answer to is whether allowing the >>user to trigger a segfault is a security problem. >> >> > >It would not be cool for a trusted language to allow such things, that's >for sure. > >You could debate back and forth about whether we ought to allow it and >warn that some versions of Perl may have exploitable bugs, but I'd >prefer to err on the side of conservatism. > > > > Well, the flipside of that is that we would force people to use the untrusted version for these ops. This isn't a hypothetical case - it was discovered by my giving Josh Berkus a solution to a problem he had which required sorting in plperl, and which he found would only run under plperlu. The question in my mind is "What are we protecting against?" ISTM it is the use of the pl as a vector to attack the machine and postgres. Does a segfault come into that category? After all, isn't it one of postgres's strengths that we can survive individual backends crashing? (Re srand, just remove "!srand" from the patch I sent in). cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > The question in my mind is "What are we protecting against?" ISTM it is > the use of the pl as a vector to attack the machine and postgres. Does a > segfault come into that category? After all, isn't it one of postgres's > strengths that we can survive individual backends crashing? Yeah, but a repeatable segfault certainly is an adequate tool for a denial-of-service attack, since it takes out everyone else's sessions along with your own. A possibly larger objection is how sure can you be that the effects will *only* be a segfault, and not say the ability to execute some user-injected machine code. regards, tom lane
Tom Lane wrote: >Andrew Dunstan <andrew@dunslane.net> writes: > > >>The question in my mind is "What are we protecting against?" ISTM it is >>the use of the pl as a vector to attack the machine and postgres. Does a >>segfault come into that category? After all, isn't it one of postgres's >>strengths that we can survive individual backends crashing? >> >> > >Yeah, but a repeatable segfault certainly is an adequate tool for a >denial-of-service attack, since it takes out everyone else's sessions >along with your own. A possibly larger objection is how sure can you be >that the effects will *only* be a segfault, and not say the ability to >execute some user-injected machine code. > > Ok, the release notes for perl 5.005 (which is now pretty ancient) say this: "Perl now contains its own highly optimized qsort() routine. The new qsort() is resistant to inconsistent comparison functions, so Perl's |sort()| will not provoke coredumps any more when given poorly written sort subroutines." Also, there were some apparent problems with sort routine reentrancy in perl < 5.6.1 - see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=60534. I have not found any more recent refs on Google to "sort" causing problems. Certainly in my testing it proved totally trivial to crash the backend with sprintf. So I suggest a reasonable position w.r.t. the danger of SEGVs would be to allow "sort" but disallow sprintf. cheers andrew
Your patch has been added to the PostgreSQL unapplied patches list at: http://momjian.postgresql.org/cgi-bin/pgpatches It will be applied as soon as one of the PostgreSQL committers reviews and approves it. --------------------------------------------------------------------------- Andrew Dunstan wrote: > > > David Helgason wrote: > > > On 14. okt 2004, at 21:09, Andrew Dunstan wrote: > > > >> It has just been brought to my attention that we are being very > >> restrictive about what we allow to be done in trusted plperl. > >> Basically we allow the :default and :base_math set of operations (run > >> perldoc Opcode or see > >> http://www.perldoc.com/perl5.8.0/lib/Opcode.html for details of what > >> these mean). In particular, we do not allow calls to perl's builtin > >> sort, which is unpleasant, and on reviewing the list it seems to me > >> we could quite reasonably allow access to pack and unpack also. bless > >> and sprintf are also likely candidates for inclusion - I have not > >> finished reviewing the list, and would welcome advice from perl gurus > >> on this. > > > > > > pack and unpack are unfortunately not safe. Very useful, but they > > allow write/read access to random memory. It's really a shame perl > > doesn't have a pragma to make them safe or have safe versions of them. > > > > Bless should be OK, unless sensitive objects are provided to the > > procedures. > > > > A postgres question I don't know the answer to is whether allowing the > > user to trigger a segfault is a security problem. If it isn't, several > > opcodes may probably be allowed, including sort and sprintf. If it is, > > well, you need only follow the perl5-porters list to know that there's > > banal perl structures are continuously being found that will segfault > > perl, some at compile time, other at runtime. > > > OK, based on this and some further thought, I have prepared the attached > patch which does the right thing, I think, both in terms of what we > allow and what we don't. > > First, we tighten security by disallowing access to srand and IO > functions on existing filehandles (other IO ops are already disallowed). > > The we relax the restrictions by allowing access to perl's sort, sprintf > and time routines. I decided against pack/unpack based on the above, and > also decided that I couldn't think of any case where bless would have > any practical use - although that might change later. I'm trying to keep > changes minimal here. I don't believe that "time" carries any > significant security implications, and I think the dangers from "sort" > and "sprintf" are not so great as to disallow them. They might cause a > SEGV in a pathological case, but that doesn't give the user access to > the machine - if they can login to postgres they can probably mount any > number of DOS attacks anyway. > > To answer David's question, the man says this about trusted functions: > "the TRUSTED flag should only be given for languages that do not allow > access to database server internals or the file system". I think the > changes I propose fit in with that statement. > > The patch also does some other inconsequential tidying of overlong > lines, and removes some unnecessary ops in the unsafe case. These are > basically cosmetic - the only significant part is replacing this: > > $PLContainer->permit(':base_math'); > > with this: > > $PLContainer->permit(qw[:base_math !:base_io !srand sort sprintf time]); > > I have tested and it appears to do the right thing, both for the things > excluded and those included. > > cheers > > andrew > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faqs/FAQ.html -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Andrew, can you or someone summarize were we left this issue and your patch? --------------------------------------------------------------------------- Andrew Dunstan wrote: > > > Tom Lane wrote: > > >Andrew Dunstan <andrew@dunslane.net> writes: > > > > > >>The question in my mind is "What are we protecting against?" ISTM it is > >>the use of the pl as a vector to attack the machine and postgres. Does a > >>segfault come into that category? After all, isn't it one of postgres's > >>strengths that we can survive individual backends crashing? > >> > >> > > > >Yeah, but a repeatable segfault certainly is an adequate tool for a > >denial-of-service attack, since it takes out everyone else's sessions > >along with your own. A possibly larger objection is how sure can you be > >that the effects will *only* be a segfault, and not say the ability to > >execute some user-injected machine code. > > > > > > Ok, the release notes for perl 5.005 (which is now pretty ancient) say this: > > "Perl now contains its own highly optimized qsort() routine. The new > qsort() is resistant to inconsistent comparison functions, so Perl's > |sort()| will not provoke coredumps any more when given poorly written > sort subroutines." > > Also, there were some apparent problems with sort routine reentrancy in > perl < 5.6.1 - see > https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=60534. > > I have not found any more recent refs on Google to "sort" causing problems. > > Certainly in my testing it proved totally trivial to crash the backend > with sprintf. > > So I suggest a reasonable position w.r.t. the danger of SEGVs would be > to allow "sort" but disallow sprintf. > > > cheers > > andrew > > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian wrote: >Your patch has been added to the PostgreSQL unapplied patches list at: > > http://momjian.postgresql.org/cgi-bin/pgpatches > >It will be applied as soon as one of the PostgreSQL committers reviews >and approves it. > >--------------------------------------------------------------------------- > > >Andrew Dunstan wrote: > > >>... >> >>The patch also does some other inconsequential tidying of overlong >>lines, and removes some unnecessary ops in the unsafe case. These are >>basically cosmetic - the only significant part is replacing this: >> >> $PLContainer->permit(':base_math'); >> >>with this: >> >> $PLContainer->permit(qw[:base_math !:base_io !srand sort sprintf time]); >> >> >> > As per previous discussions, please remove "!srand" and "sprintf" if/when applying. cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > It has just been brought to my attention that we are being very > restrictive about what we allow to be done in trusted plperl. > ... > OK, based on this and some further thought, I have prepared the attached > patch which does the right thing, I think, both in terms of what we > allow and what we don't. Applied, with changes to allow srand and disallow sprintf, as per subsequent discussion. regards, tom lane
> Applied, with changes to allow srand and disallow sprintf, as per > subsequent discussion. How about allowing: use utf8; use locale; ? Kind Regards, John
John Hansen wrote: >>Applied, with changes to allow srand and disallow sprintf, as per >>subsequent discussion. >> >> > >How about allowing: > >use utf8; >use locale; > >? > > > > I think it is *way* too late in the dev cycle to be proposing this. Maybe it should be a TODO item - I at least don't have time even to think about the implications os using these pragmas. The effect of the first is achievable via an environment setting, I believe. If you need these badly enough, use plperlu where there are no restrictions to overcome - the big problem is that 'use anything' requires that we enable the 'require' op, and that is certainly not going to happen without a great deal of thought. cheers andrew
> I think it is *way* too late in the dev cycle to be proposing this. > Maybe it should be a TODO item - I at least don't have time even to > think about the implications os using these pragmas. The effect of the > first is achievable via an environment setting, I believe. > > If you need these badly enough, use plperlu where there are no > restrictions to overcome - the big problem is that 'use anything' > requires that we enable the 'require' op, and that is certainly not > going to happen without a great deal of thought. Fair enough, was just a suggestion as they seem obviously useful, even to the non-superuser plperl programmer. TODO item would suffice :) ... John
Uh, what was the TODO here? I forgot. --------------------------------------------------------------------------- John Hansen wrote: > > I think it is *way* too late in the dev cycle to be proposing this. > > Maybe it should be a TODO item - I at least don't have time even to > > think about the implications os using these pragmas. The effect of the > > first is achievable via an environment setting, I believe. > > > > If you need these badly enough, use plperlu where there are no > > restrictions to overcome - the big problem is that 'use anything' > > requires that we enable the 'require' op, and that is certainly not > > going to happen without a great deal of thought. > > Fair enough, was just a suggestion as they seem obviously useful, even > to the non-superuser plperl programmer. > > TODO item would suffice :) > > ... John > > > ---------------------------(end of broadcast)--------------------------- > TIP 3: if posting/reading through Usenet, please send an appropriate > subscribe-nomail command to majordomo@postgresql.org so that your > message can get through to the mailing list cleanly > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > Uh, what was the TODO here? I forgot. I think we already did what we decided was safe there. regards, tom lane
Bruce Momjian said: > > Uh, what was the TODO here? I forgot. > > John wanted us to allow use of the 'locale' and 'utf8' pragmas in trusted code. If there's a TODO it would be to investigate the possibility, as I am very far from certain that there is a simple way to do it safely right now. Maybe when we get plperl using GUC settings and running some interpreter initialisation it could be done. These are things on my agenda. cheers andrew --------------------------------------------------------------------------- > > John Hansen wrote: >> > I think it is *way* too late in the dev cycle to be proposing this. >> > Maybe it should be a TODO item - I at least don't have time even to >> > think about the implications os using these pragmas. The effect of >> > the first is achievable via an environment setting, I believe. >> > >> > If you need these badly enough, use plperlu where there are no >> > restrictions to overcome - the big problem is that 'use anything' >> > requires that we enable the 'require' op, and that is certainly not >> > going to happen without a great deal of thought. >> >> Fair enough, was just a suggestion as they seem obviously useful, even >> to the non-superuser plperl programmer. >> >> TODO item would suffice :) >> >> ... John
"Andrew Dunstan" <andrew@dunslane.net> writes: > John wanted us to allow use of the 'locale' and 'utf8' pragmas in trusted > code. You know, there's something twisted in postgres's naming scheme here. How is it that "trusted" languages the ones that need a sandbox? and "untrusted" languages the ones that get to run amok without restrictions? I would have thought it would be the other way around. -- greg
On Thu, 2004-12-02 at 02:21 -0500, Greg Stark wrote: > "Andrew Dunstan" <andrew@dunslane.net> writes: > > > John wanted us to allow use of the 'locale' and 'utf8' pragmas in trusted > > code. > > You know, there's something twisted in postgres's naming scheme here. How is > it that "trusted" languages the ones that need a sandbox? and "untrusted" > languages the ones that get to run amok without restrictions? > > I would have thought it would be the other way around. It's not that you trust the language, it that you trust the PostgreSQL despite the language. --