[Zope-dev] Security problems importing from python package.

Clemens Robbenhaar zope-dev@zope.org
Mon, 25 Nov 2002 13:07:45 +0100


At Thu, 21 Nov 2002 12:16:09 +0000, Chris Withers wrote:

 > I'm trying to get stripogram working from Script(Pythons). I thought I had it, 
 > but it appears I don't.
 > 
 > I added the following in the __init__.py of the stripogram package:
 > 
 > try:
 >      from AccessControl import ModuleSecurityInfo,allow_module
 > except ImportError:
 >      # no Zope around
 >      raise
 > else:
 >      allow_module('stripogram')
 >      ModuleSecurityInfo('stripogram').declareObjectPublic()
 >      ModuleSecurityInfo('stripogram').declarePublic('html2text', 'html2safehtml')
 > 

 This issue is most probably resolved somewhere in between, but I can
not find any trace of this at zope-dev@zope.org nor zope@zope.org, thus I
drop in my 2 cents here.


  I did just now run into a similar problem, and may offer the following
explanation after some debugging:

 It seems the 'allow_module', etc, gets not executed by Zope in advance,
except if this is the __init__.py of a 'Product', or this module is
imported by some core module or product. This is quite standard python
behaviour; the module is not initialized before import, and Zope does
some extra work to initialize all products on startup.


 If one tries to import the code from a python script, the security
machinery first check, if the module has some security info, and imports
it afterwards, if the info is found. But as the module is not imported
anyway, it is not initialized, and has not such info and thus will not
be allowed for import. 
 It seems there is some chicken and egg problem here, or I have missed
something completely.

 The workaround is to insert a dummy 'import stripogram' in some
product, which triggers the security info creation -- or make the little
helper scripts a product of its own.


 > I don't think either the allow_module or the declareObjectPublic() should be 
 > necessary. However, the declareObjectPublic at least made this test pass:
 > 
 >      from Products.PythonScripts.PythonScript import PythonScript
 >      theScript = PythonScript('test')
 >      theScript.ZBindings_edit({})
 >      theScript.write("from stripogram import html2text\nreturn 
 > html2text('<i>hello</i>')")
 >      theScript._makeFunction()
 >      self.assertEqual(theScript(),'hello')
 > 

This works, as Your test code imports something via file system (no
access restriction) from module "stripogram" first and then creates the
test script, which finds the module info on import as the module is
intialized yet.

 > But even adding the 'allow_module' won't let the following Script (Python) 
 > created through the ZMI work:
 > 
 > from stripogram import html2text
 > 
 > The error I get is:
 > 
 >   Error Type: ImportError
 > Error Value: import of "stripogram" is unauthorized

 In this case the module has not been initialized yet, and the TTW
access is the first import, which failes due to the security
restrictions problem mentioned above.


 Hope this helps; and hope someone can point me out I am wrong on the
chicken and egg problem of 'non-Product' module import. 


Cheers,
Clemens