Hello, after Chris Withers lightning talk at EPC 2008 I had a closer look at the implementation of Python Scripts in Zope 2.11. While I have not yet been able to break out of the restricted environment without help from installed products, there are a few denial-of-service attacks which can easily be deployed on sites allowing adding Python Scripts to a user folder: 1. Attack: Put this into a "Script (Python)" object and run it: return 'kaboom'.encode('test.testall') This results in a denial-of-service, since Zope will hang running the Python test suite. The reason for this is a problem in the way the encoding search function works in Python 2.4. This was changed in 2.5 to no longer allow searching for codecs outside the encodings package. 2. Attack: Put this into a "Script (Python)" object and run it: raise SystemExit This shuts down Zope. The Python Script environment should obviously catch such exceptions and not let them propagate up the call stack. I found the second attack rather surprising, as it doesn't require deep knowledge about Python's interna. Regards, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 12 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
Sorry about the posting. I should have known better not to use a public mailing list for these sort of posts. Apologies, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 12 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
*sigh* I wished that both exploits were reported to the Zope bugtracker in order to work on solutions before making the exploits public. --On 12. August 2008 13:41:04 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
Hello,
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
This results in a denial-of-service, since Zope will hang running the Python test suite.
The reason for this is a problem in the way the encoding search function works in Python 2.4. This was changed in 2.5 to no longer allow searching for codecs outside the encodings package.
That's pretty obscure behavior of Python 2.4...anyway.
2. Attack:
Put this into a "Script (Python)" object and run it:
raise SystemExit
This shuts down Zope.
The Python Script environment should obviously catch such exceptions and not let them propagate up the call stack.
See the followup on <https://bugs.launchpad.net/zope2/+bug/257269> There is a patch available that solves the problem. Andreas
--On 12. August 2008 14:16:44 +0200 Andreas Jung <lists@zopyx.com> wrote:
*sigh*
I wished that both exploits were reported to the Zope bugtracker in order to work on solutions before making the exploits public.
--On 12. August 2008 13:41:04 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
Hello,
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
This results in a denial-of-service, since Zope will hang running the Python test suite.
The reason for this is a problem in the way the encoding search function works in Python 2.4. This was changed in 2.5 to no longer allow searching for codecs outside the encodings package.
That's pretty obscure behavior of Python 2.4...anyway.
The followup for this issue is also on Launchpad including a possible solution: <https://bugs.launchpad.net/zope2/+bug/257276> The patches/monkey patches for both issues need review and testing. I am now working on a security advisory. For the hotfixes and testing I need definitely help since I am the road for the rest of the week and pretty busy and limited network connectivity. Andreas
--On 12. August 2008 16:05:47 +0200 Andreas Jung <lists@zopyx.com> wrote:
--On 12. August 2008 14:16:44 +0200 Andreas Jung <lists@zopyx.com> wrote:
*sigh*
I wished that both exploits were reported to the Zope bugtracker in order to work on solutions before making the exploits public.
--On 12. August 2008 13:41:04 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
Hello,
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
This results in a denial-of-service, since Zope will hang running the Python test suite.
The reason for this is a problem in the way the encoding search function works in Python 2.4. This was changed in 2.5 to no longer allow searching for codecs outside the encodings package.
That's pretty obscure behavior of Python 2.4...anyway.
The followup for this issue is also on Launchpad including a possible solution:
<https://bugs.launchpad.net/zope2/+bug/257276>
The patches/monkey patches for both issues need review and testing.
I am now working on a security advisory.
For the hotfixes and testing I need definitely help since I am the road for the rest of the week and pretty busy and limited network connectivity.
I created a preliminary hotfix <http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz/view> After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8. That's all I can do for now - please test and improve the hotfix if needed. Thanks, Andreas
Thanks a lot for taking care of these issues, Andreas! Andreas Jung wrote:
--On 12. August 2008 16:05:47 +0200 Andreas Jung <lists@zopyx.com> wrote:
--On 12. August 2008 14:16:44 +0200 Andreas Jung <lists@zopyx.com> wrote:
*sigh*
I wished that both exploits were reported to the Zope bugtracker in order to work on solutions before making the exploits public.
--On 12. August 2008 13:41:04 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
Hello,
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
This results in a denial-of-service, since Zope will hang running the Python test suite.
The reason for this is a problem in the way the encoding search function works in Python 2.4. This was changed in 2.5 to no longer allow searching for codecs outside the encodings package.
That's pretty obscure behavior of Python 2.4...anyway.
The followup for this issue is also on Launchpad including a possible solution:
<https://bugs.launchpad.net/zope2/+bug/257276>
The patches/monkey patches for both issues need review and testing.
I am now working on a security advisory.
For the hotfixes and testing I need definitely help since I am the road for the rest of the week and pretty busy and limited network connectivity.
I created a preliminary hotfix
<http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz/view>
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
That's all I can do for now - please test and improve the hotfix if needed.
Thanks, Andreas
------------------------------------------------------------------------
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
--On 12. August 2008 17:19:54 +0200 Andreas Jung <lists@zopyx.com> wrote:
I created a preliminary hotfix
<http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz/view>
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated). Andreas
--On 12. August 2008 17:31:06 +0200 Andreas Jung <lists@zopyx.com> wrote:
--On 12. August 2008 17:19:54 +0200 Andreas Jung <lists@zopyx.com> wrote:
I created a preliminary hotfix
<http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz/view>
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated).
Update: the hotfix although works for Zope 2.8 (tested with a running Zope instance - however the testrunner does not seem to import Hotfix though the included tests under 2.8 aren't found/executed). Andreas
Andreas Jung, on 2008-08-12:
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated).
Update: the hotfix although works for Zope 2.8 (tested with a running Zope instance - however the testrunner does not seem to import Hotfix though the included tests under 2.8 aren't found/executed).
In Zope 2.8, when I place the Hotfix in the Products dir of the instance, the two tests pass when I run the tests like this: bin/zopectl test --dir=Products/Hotfix_20080812/ That's with: http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz I tested on Zope 2.8, 2.9, 2.10, 2.11. All with python 2.4. Without the hotfix "raise SystemExit" crashed Zope. I could not confirm the other problem; that just gave me a LookupError. With the hotfix in the Products dir of the instance, the crash did not occur and the tests passed. Marvelous! Thanks Andreas! -- Maurits van Rees | http://maurits.vanrees.org/ Work | http://zestsoftware.nl/ "This is your day, don't let them take it away." [Barlow Girl]
Maurits van Rees, on 2008-08-12:
That's with: http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz
Oh, that tarball contains a .svn directory... I took the liberty of committing a change to the text of the raised ValueError to make it a proper sentence. Old: SystemExit can not raised with a PythonScript new: SystemExit can not be raised within a PythonScript -- Maurits van Rees | http://maurits.vanrees.org/ Work | http://zestsoftware.nl/ "This is your day, don't let them take it away." [Barlow Girl]
--On 12. August 2008 17:14:15 +0000 Maurits van Rees <m.van.rees@zestsoftware.nl> wrote:
Andreas Jung, on 2008-08-12:
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated).
Update: the hotfix although works for Zope 2.8 (tested with a running Zope instance - however the testrunner does not seem to import Hotfix though the included tests under 2.8 aren't found/executed).
In Zope 2.8, when I place the Hotfix in the Products dir of the instance, the two tests pass when I run the tests like this:
bin/zopectl test --dir=Products/Hotfix_20080812/
That's with: http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz
I tested on Zope 2.8, 2.9, 2.10, 2.11. All with python 2.4. Without the hotfix "raise SystemExit" crashed Zope. I could not confirm the other problem; that just gave me a LookupError. With the hotfix in the Products dir of the instance, the crash did not occur and the tests passed.
Thanks for further testing. I released V 0.2 of the hotfix containing your fixes. The hotfix also works with Zope 2.7...this should be enough. If there are no objections I would like to release the hotfix officially at some time tomorrow. Andreas
On 2008-08-12 20:49, Andreas Jung wrote:
--On 12. August 2008 17:14:15 +0000 Maurits van Rees <m.van.rees@zestsoftware.nl> wrote:
Andreas Jung, on 2008-08-12:
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated).
Update: the hotfix although works for Zope 2.8 (tested with a running Zope instance - however the testrunner does not seem to import Hotfix though the included tests under 2.8 aren't found/executed).
In Zope 2.8, when I place the Hotfix in the Products dir of the instance, the two tests pass when I run the tests like this:
bin/zopectl test --dir=Products/Hotfix_20080812/
That's with: http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz
I tested on Zope 2.8, 2.9, 2.10, 2.11. All with python 2.4. Without the hotfix "raise SystemExit" crashed Zope. I could not confirm the other problem; that just gave me a LookupError. With the hotfix in the Products dir of the instance, the crash did not occur and the tests passed.
The .encode() example will only trigger if the Python test suite is installed in your Python version. Some distros move this into a separate package, so if this is not installed, that particular example won't work.
Thanks for further testing. I released V 0.2 of the hotfix containing your fixes. The hotfix also works with Zope 2.7...this should be enough. If there are no objections I would like to release the hotfix officially at some time tomorrow.
Please add a warning to be extra careful when enabling edit/create/modify access to PythonScripts in the ZMI. Thanks, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 13 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
Thanks Andreas, for creating a hotfix for this issue!
--On 12. August 2008 17:14:15 +0000 Maurits van Rees <m.van.rees@zestsoftware.nl> wrote:
Andreas Jung, on 2008-08-12:
After rough test: it seems to work for Zope trunk, 2.10 and 2.11 but has a failure for Zope 2.8.
I forgot to mention that the hotfix also seems to work for Zope 2.9. (third-party confirmations are highly appreciated).
Update: the hotfix although works for Zope 2.8 (tested with a running Zope instance - however the testrunner does not seem to import Hotfix though the included tests under 2.8 aren't found/executed).
In Zope 2.8, when I place the Hotfix in the Products dir of the instance, the two tests pass when I run the tests like this:
bin/zopectl test --dir=Products/Hotfix_20080812/
That's with: http://www.zope.org/advisories/Hotfix_20080812_0.1.tar.gz
I tested on Zope 2.8, 2.9, 2.10, 2.11. All with python 2.4. Without the hotfix "raise SystemExit" crashed Zope. I could not confirm the other problem; that just gave me a LookupError. With the hotfix in the Products dir of the instance, the crash did not occur and the tests passed.
Thanks for further testing. I released V 0.2 of the hotfix containing your fixes. The hotfix also works with Zope 2.7...this should be enough. If there are no objections I would like to release the hotfix officially at some time tomorrow.
Andreas ------------------------------------------------------------------------
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
-- Martijn Jacobs Four Digits, Internet Solutions a: Willemsplein 15-1 6811 KB Arnhem NL kvk: 091621370000 | btw: 8161.22.234.B01 e-mail: martijn@fourdigits.nl | web: http://www.fourdigits.nl tel: +31 (0)26 44 22 700 | fax: +31 (0)84 22 06 117
M.-A. Lemburg wrote at 2008-8-12 13:41 +0200:
... While I have not yet been able to break out of the restricted environment without help from installed products, there are a few denial-of-service attacks which can easily be deployed on sites allowing adding Python Scripts to a user folder:
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
Attacks like this are well known and it is very difficult to prevent them reliably: Script (Python) (for good reasons) allows "while" and with it it is trivial to * create infinite loops * consume an unbound amount of memory That we hear very few problem reports in this respect indicates that these "insecurities" have very little practical importance -- maybe, because few installations grant the creation of scripts to untrusted people. -- Dieter
On 2008-08-16 08:00, Dieter Maurer wrote:
M.-A. Lemburg wrote at 2008-8-12 13:41 +0200:
... While I have not yet been able to break out of the restricted environment without help from installed products, there are a few denial-of-service attacks which can easily be deployed on sites allowing adding Python Scripts to a user folder:
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall')
Attacks like this are well known and it is very difficult to prevent them reliably:
Script (Python) (for good reasons) allows "while" and with it it is trivial to
* create infinite loops
* consume an unbound amount of memory
That we hear very few problem reports in this respect indicates that these "insecurities" have very little practical importance -- maybe, because few installations grant the creation of scripts to untrusted people.
... and that's good :-) I think the only problem with PythonScripts is that they advertise themselves as providing a secure way to run Python code (see the help documentation) and that can potentially cause serious security problems. In my experience, attempts to create a sandbox that protects sufficiently against unwanted resource usage are either too restrictive and slow to make them useful or have problems preventing DOS attacks. It's usually a lot better (and more efficient) to use trusted code only. BTW: The reason why I had a look at these was that Chris Withers mentioned at EuroPython that they are currently causing delays in the Python 2.5 adoption (or at least are one of the reasons for them). -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 16 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
--On 16. August 2008 13:11:13 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
In my experience, attempts to create a sandbox that protects sufficiently against unwanted resource usage are either too restrictive and slow to make them useful or have problems preventing DOS attacks.
I think you can't solve the issue with the standard technology we have in CPython. I remember that Python once had a restricted execution environment. Wasn't it buggy as hell? RestrictedPython of Zope surely similar problems. As with all such restricted execution environment (not only in Zope): they are attackable.
It's usually a lot better (and more efficient) to use trusted code only.
Definitely. A common development pattern is the usage of CMF and portal_skins where you work with PythonScripts on the filesystem. The scripts themselves still run under the control of RestrictedPython however the whole development model can be regarded as being trusted.
BTW: The reason why I had a look at these was that Chris Withers mentioned at EuroPython that they are currently causing delays in the Python 2.5 adoption (or at least are one of the reasons for them).
Is Chris' talk somewhere online? Andreas
On 2008-08-16 13:39, Andreas Jung wrote:
--On 16. August 2008 13:11:13 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
In my experience, attempts to create a sandbox that protects sufficiently against unwanted resource usage are either too restrictive and slow to make them useful or have problems preventing DOS attacks.
I think you can't solve the issue with the standard technology we have in CPython. I remember that Python once had a restricted execution environment. Wasn't it buggy as hell?
It used to be fairly safe at one point (I think around Python 1.4), but maintenance was then dropped and so it was deprecated later on. The main module was called Bastion.py.
RestrictedPython of Zope surely similar problems. As with all such restricted execution environment (not only in Zope): they are attackable.
Right. While some of them are fairly good at restricting access to e.g. the file system or object system, they usually lack protection against unlimited CPU and memory use. A multi-threaded approach makes hard as well, since killing of a thread often doesn't release the associated resources. In a multi-process environment things are easier, since the OS will take care of most of the monitoring and apply this at a much lower level.
It's usually a lot better (and more efficient) to use trusted code only.
Definitely. A common development pattern is the usage of CMF and portal_skins where you work with PythonScripts on the filesystem. The scripts themselves still run under the control of RestrictedPython however the whole development model can be regarded as being trusted.
BTW: The reason why I had a look at these was that Chris Withers mentioned at EuroPython that they are currently causing delays in the Python 2.5 adoption (or at least are one of the reasons for them).
Is Chris' talk somewhere online?
It was a lightning talk. I'm not sure whether those are online somewhere. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 16 2008)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
Andreas Jung wrote:
BTW: The reason why I had a look at these was that Chris Withers mentioned at EuroPython that they are currently causing delays in the Python 2.5 adoption (or at least are one of the reasons for them).
Is Chris' talk somewhere online?
Sorry, they were just quick lightning talks. Let me know if you'd like me to send you (or anyone else) a copy off list... cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 M.-A. Lemburg wrote:
On 2008-08-16 08:00, Dieter Maurer wrote:
M.-A. Lemburg wrote at 2008-8-12 13:41 +0200:
... While I have not yet been able to break out of the restricted environment without help from installed products, there are a few denial-of-service attacks which can easily be deployed on sites allowing adding Python Scripts to a user folder:
1. Attack:
Put this into a "Script (Python)" object and run it:
return 'kaboom'.encode('test.testall') Attacks like this are well known and it is very difficult to prevent them reliably:
Script (Python) (for good reasons) allows "while" and with it it is trivial to
* create infinite loops
* consume an unbound amount of memory
That we hear very few problem reports in this respect indicates that these "insecurities" have very little practical importance -- maybe, because few installations grant the creation of scripts to untrusted people.
... and that's good :-)
I think the only problem with PythonScripts is that they advertise themselves as providing a secure way to run Python code (see the help documentation) and that can potentially cause serious security problems.
In my experience, attempts to create a sandbox that protects sufficiently against unwanted resource usage are either too restrictive and slow to make them useful or have problems preventing DOS attacks.
It's usually a lot better (and more efficient) to use trusted code only.
Agreed. The major advantages of through-the-web coding are that changes don't require server restarts, and that programmers don't need filesystem access on the server. Both of those aren't much help during development, at least in a "developer sandbox" model, but they have been important in the past for apps which were in production.
BTW: The reason why I had a look at these was that Chris Withers mentioned at EuroPython that they are currently causing delays in the Python 2.5 adoption (or at least are one of the reasons for them).
I think the big issue is that the changes to the underlying AST model in 2.5 need review against our TTW guards. The set of people who can do that review is pretty small: it needs a fairly deep understanding of Python's low-level internals. Last time we did the drill (for Python 2.4), there were a few more Python core developers around whose day jobs motivated the review. At this point, the intersection of the available with the able is pretty small. ;( Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFIpuee+gerLs4ltQ4RAjqWAJ9Efg90jVLcmyMoU7catEPahhULsACfUzn3 Zd1aD3DGQqmFsK4iKbv1I0A= =wc75 -----END PGP SIGNATURE-----
participants (8)
-
Andreas Jung -
Chris Withers -
Dieter Maurer -
M.-A. Lemburg -
Martijn Jacobs -
Maurits van Rees -
Philipp von Weitershausen -
Tres Seaver