0

I need to block some modules and I need to know if some module don't import it. So I need a way to traverse all modules to see if a module have sub module, that I need to block.

Is there a way to check all installed modules for existence of modules I need to block? I don't need cross-platform solution.

jcubic
  • 61,973
  • 54
  • 229
  • 402
  • 2
    What do browsers have to do with it? – Björn Pollex Mar 17 '11 at 20:22
  • This is unclear. do you wish to stop python from running dangerous site-packages? because you could just remove them from you installation (could have unforseen effects for other programs). if you want to know what's imported, surely you could step through or enable verbose imports... – theheadofabroom Mar 17 '11 at 21:14
  • Unfortunately I don't have access to root account not event to the shell. If I could I will do this. – jcubic Mar 17 '11 at 21:28
  • +1 @Space_C0wb0y it suppose to be cross-platfrom. – jcubic Mar 17 '11 at 21:28
  • it is for trypython.jcubic.pl as he has stated in a response to one of the answers - it runs in a browser under `Python 2.4.3 (#1, Nov 15 2010, 17:50:57) [GCC 4.1.2 20080704 (CloudLinux 4.1.2-48)] on linux2` – theheadofabroom Mar 18 '11 at 17:17
  • Fw: I mean No access to the real shell (like shh). – jcubic Mar 19 '11 at 01:10

4 Answers4

2

Sounds like you're trying to build a sandbox. The Python wiki lists some good approaches.

I took a look at your webapp and it's quite easy to hack:

  • you can import modules like ctypes.util or logging or hundreds of others that import os, sys.
  • you can even import the modules directly like x = [__import__("os")]
  • __builtins__['__import__']("os") works too

and those are just the first things I tried.

If you really want to do this then the only reasonable approach is to built a whitelist of safe modules. You have to though the sources for each module and determine if they import only safe modules.

I don't think you can reach any kind of real security without changing the Python interpreter though. There are probably way less obvious ways to get a hold of these modules and you'd have to find them all.

Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
  • Yes your right. This is for this site http://trypython.jcubic.pl/, and I know about this module, but I can't install anything on this server. But thanks anyway. – jcubic Mar 17 '11 at 21:26
  • 2
    @jcubic: That app is quite insecure, I managed to load os and sys and start a bash shell. – Jochen Ritzel Mar 17 '11 at 22:49
  • I do this find /usr/lib/python | xargs grep "import os" and I have that list but I want to know If I can do this from python. – jcubic Mar 19 '11 at 01:04
  • @jcubic: That's not enough. Say module xy imports os, that means xy is unsafe too. Now all modules that import xy are unsafe too and you have to repeat the process. Not to mention that you can do "import something, os" – Jochen Ritzel Mar 19 '11 at 01:23
1

This will prevent the behaviour @Jochen observed (assuming you populate your list a little more fully)

def __import__(name, globals={}, locals={}, fromlist=[], level=-1, oldfunc=__import__):
    checklist = fromlist[:]
    checklist.extend(name.split('.'))
    for check in checklist:
        if check in ('os', 'sys'):
            print 'Uh-uh I\'m better than that...'
            return
    oldfunc(name, globals, locals, fromlist, level)

Trying it on your site gives:


>>> def __import__(name, globals={}, locals={}, fromlist=[], level=-1, oldfunc=__import__):
    checklist = fromlist[:]
    checklist.extend(name.split('.'))
    for check in checklist:
        if check in ('os', 'sys'):
            print 'Uh-uh I\'m better than that...'
            return
    oldfunc(name, globals, locals, fromlist, level)
>>> __import__('os')
Uh-uh I'm better than that...
>>> x = [__import__('os')]
Uh-uh I'm better than that...
>>>  

It doesn't however change the default import behaviour. It looks like you're stopping there from being a literal with the name 'os' in it. If you can find a way of editing the actual import behaviour to call this function (I'm not hopeful that this is even possible, but it's worth looking into) then you can allow literals with names along the lines of dangerous imports - as well as allowing people to use variable names that they like, this will make it harder to work out what you're doing to prevent imports, and therefore getting around it...

theheadofabroom
  • 20,639
  • 5
  • 33
  • 65
  • +1 Wow this is awesome. I can't give you a bounty because I give it @Jochen before I read your post. Sorry. – jcubic Mar 19 '11 at 01:06
1

If you are trying to sandbox Python, the only real implementation I know of that provides this without OS support is PyPy. There was a thread on python-dev a year or two ago discussing sandboxing and people broke all the attempts by doing things like peeking into the stack to obtain modules that couldn't be locally imported, bytecode manipulation and a hundred other things.

A couple of extra answers are discussed here as well.

Community
  • 1
  • 1
Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
0

If you just want to block modules, you may be able to play with sys.path variable and use it to make sure that it only contains whitelisted modules (or excludes blacklisted ones). This way the Python interpreter won't be able to find disallowed modules and therefore any import of those will fail.

http://docs.python.org/tutorial/modules.html (see 6.1.2: “The Module Search Path”)

user268396
  • 11,576
  • 2
  • 31
  • 26
  • Thanks for answer but I want to execute python code and block dangerous modules. And this don't work "import sys; sys.path = []; import os". I what to block os (os in this case) from exec. – jcubic Mar 15 '11 at 14:59