[Python-Dev] Challenge: Please break this! (a.k.a restricted mode revisited)

Chris Angelico rosuav at gmail.com
Tue Apr 12 04:57:37 EDT 2016

On Tue, Apr 12, 2016 at 6:17 PM, Paul Moore <p.f.moore at gmail.com> wrote:
> Well, I'll ask the obvious question, then. In allowing "import" did
> you allow "import ctypes"? If so, then I win :-) Or did you explicitly
> whitelist certain modules? And if so, which ones are they, and did I
> succeed if I manage to import a module you hadn't whitelisted?

The module whitelist is given at the top of the source code:

_SAFE_MODULES = frozenset((
    "base64", "binascii", "bisect", "calendar", "cmath", "crypt", "datetime",
    "decimal", "enum", "errno", "fractions", "functools", "hashlib", "hmac",
    "ipaddress", "itertools", "math", "numbers", "queue", "re", "statistics",
    "textwrap", "unicodedata", "urllib.parse",

And yes, you win if you get another module. Interestingly, you're
allowed to import urllib.parse, but not urllib itself; but "import
urllib.parse" makes urllib available - and, since modules inside
modules are blacklisted, "urllib.parse" doesn't exist

You can access the decimal module, and call decimal.getcontext(). This
returns the same default context object that the "outer" Python uses;
consequently, this sandboxing technique MUST NOT be used in any
program that, now or ever in the future, uses the decimal module (or
at least its default context; but I'm not sure how you'd be absolutely
sure you never EVER use the default context).

Even more curiously, you can "import fractions", but you don't get
fractions.Fraction - though you *do* get fractions.Decimal. And
importing enum gives you EnumMeta, but metaclasses seem to be broken,
and you can't get enum.Enum.

The sandbox code assumes that an attacker cannot create files in the
current directory.

rosuav at sikorsky:~/tmp/unsafe$ echo 'import sys; real_module = lambda
mod: sys.modules[mod]' >hashlib.py
rosuav at sikorsky:~/tmp/unsafe$ ./unsafe.py -i
Python 3.6.0a0 (default:78b84ae0b745+, Apr  6 2016, 03:43:18)
[GCC 5.3.1 20160323] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> hashlib.real_module("sys")
<module 'sys' (built-in)>

Setting LC_ALL and then working with calendar.LocaleTextCalendar()
causes locale files to be read. I'm not sure if you can turn that into
an exploit, but the attack surface depends on the installed locales on
the system.

This is still a massive game of whack-a-mole.


More information about the Python-Dev mailing list