Closed Ryan-Gordon1 closed 4 years ago
Ryan Gordon wrote at 2019-11-14 06:45 -0800:
While using RestrictedPython a use case I would like to have is not allow the import of certain packages but allow others. For example I want to allow
json
but disallowrequests
. Is this currently possible by modifying safe_builtins or safe_utilities?
RestrictedPython
delegates such decisions to an external policy
package.
I am using RestrictedPython
in the context of Zope
. Zope
's
policy package is AccessControl
. AccessControl
implements
the policy "import forbidden unless explicitly allowed".
To allow the import of a module, it has a function allow_module
(and various other allow_*
for other kinds of objects).
Summary: you can configure RestrictedPython
to do what you want.
Either use AccessControl
directly or design your own
policy package using AccessControl
as some form of blueprint.
This was very helpful @d-maurer thank you for your comment. I have started to use AccessControl directly and can now achieve was asking. Would it be helpful if I did a write up on this ?
I have another question which I can file as a separate issue if thats better. I can now explicitly allow a module using AccessControl, I can also mark modules as private with the same package. My curious question now is if its possible to allow the importation of a module/package but disallow the importation of a certain module within that package.
For example: We see the os
package which has a number of modules within it. Is it possible to allow one module from within the package and restrict another ? Maybe allowing os.st
and disallowing others.
Ryan Gordon wrote at 2019-11-20 01:19 -0800:
... My curious question now is if its possible to allow the importation of a module/package but disallow the importation of a certain module within that package.
If you allow the import of a package, you allow only its import, not that
of contained modules/subpackages. You must use allow_module
for
contained modules/subpackages to allow their import.
Usually, the imported module content has further usage restrictions
(e.g. you would use ModuleSecurityInfo
/ClassSecurityInfo
/allow_class
etc. to control the use of the module content).
I believe (event though I have not checked) that a allow_module("os.path")
allows the import of "os.path", but not that of "os".
I avoid potentially tricky questions like this by providing
a collection module (or several ones) which uses unrestricted
Python to provide access to everything which should
be available to restricted Python and then allow_module
this module.
This allows to precisely control which is availabe to restricted
Python without very deep knowledge about internals.
If you allow the import of a package, you allow only its import, not that of contained modules/subpackages.
This was my expectation also and it works with a direct import
If I allow_module('os')
I cannot import os.path
If I allow_module('os.path')
I can import os.path
But something I noticed is that if I allow_module(os)
I am not able to import os.path
but I am able to import it from the package like this from os import path
I avoid potentially tricky questions like this by providing a collection module (or several ones) which uses unrestricted Python to provide access to everything which should be available to restricted Python and then
allow_module
this module.
I will review this as an approach to solve this. Thank you for the guidance on this issue!
@Ryan-Gordon1 Can this issue be closed ?
Yes, I can now restrict a number of packages and allow others through RestrictedPython. So we can close this. Would be good to keep a note of this comment:
But something I noticed is that if I allow_module(os) I am not able to
import os.path
but I am able to import it from the package like thisfrom os import path
Ryan Gordon wrote at 2019-11-20 02:27 -0800:
... But something I noticed is that if I
allow_module(os)
I am not able toimport os.path
but I am able to import it from the package like thisfrom os import path
This could be a bug or something normal.
If you have a package/module "M" and an attribute "A" in "M",
then from M import A
only involves importing "M".
Thus, if importing os
imports os.path
as a side effect
and makes path
available as attribute, your observed
behaviour is to be expected. I just checked, that
(at least under Python 2), this is indeed the case.
The approach below depends on this behaviour: whatever
becomes an attribute ("A") of an imported module "M", can be accessed
later via from M import A
.
I avoid potentially tricky questions like this by providing a collection module (or several ones) which uses unrestricted Python to provide access to everything which should be available to restricted Python and then
allow_module
this module. I will review this as an approach to solve this. Thank you for the guidance on this issue!
Thus, if importing
os
importsos.path
as a side effect and makespath
available as attribute, your observed behaviour is to be expected. I just checked, that (at least under Python 2), this is indeed the case.
Thank you for investigating this @d-maurer and confirming that (on Python2) it is expected.
While using RestrictedPython a use case I would like to have is not allow the import of certain packages but allow others. For example I want to allow
json
but disallowrequests
. Is this currently possible by modifying safe_builtins or safe_utilities?