DISQUS

Asktav: Update on Securing the Python Interpreter

  • Mark Seaborn · 9 months ago
    Your Namespace() function is not safe. Like Python's locals() and globals() it does not follow capability discipline and is getting its inputs seemingly from nowhere by looking up the stack. You can use it to violate the encapsulation of objects that take callback functions::

    from safelite import FileReader, Namespace

    def unsuspecting(func):
    x = "secret"
    def y():
    return x
    return func()

    # prints "secret"
    print unsuspecting(Namespace).y()

    You need to find an alternative. I suspect that if you want to use Cajita-style multiple closure objects, you will find that rather than writing code like this::

    def make_point(x, y):
    def get_x():
    return x
    def get_y():
    return y
    return Namespace()

    you are going to have to write code that repeats itself::

    def make_point(x, y):
    def get_x():
    return x
    def get_y():
    return y
    return MakeObject({"get_x": get_x, "get_y": get_y})

    This problem does not occur in Javascript where multi-statement functions can be embedded inside expressions. Python is just syntactically stricter.

    See http://www.eros-os.org/pipermail/e-lang/2008-Au...

    Mark
  • tav · 9 months ago
    Hey Mark,

    Thank you for this!

    Sorry that I missed the discussion on e-lang -- wasn't aware that a similar approach was being explored on there! I see both were inspired by Ka-Ping Yee's post years ago...

    The Namespace function initially only supported the explicit:

    Namespace(get_x=get_x, get_y=get_y)
    Namespace(get_x, get_y) # using __name__

    It still supports this format. But, as you rightly pointed out in that email, it quickly got tedious and I streamlined it ;p

    By removing the implicit format the attack you show goes away... and we go back to a pure capability base. Perhaps we could start from there?

    As for your concerns of efficiency in the email, in my C/Cython implementation of Namespace:

    http://github.com/tav/plexnet/blob/9f2ca9505e57...

    I use a trick from the PyPy guys and share the dictionary *keys* amongst the various Namespace objects. This is still nowhere near as efficient as Python classes, but it at least saves on memory -- which could be considerable when lots of similar Namespace objects are created.

    And speaking of PyPy, I'm increasingly tending towards using it as a showcase:

    * Fork the Python implementation on PyPy
    * Add native support for object capability and some distributed features
    * Bootstrap from that point and demonstrate the viability/utility of the ideas

    We could perhaps even take a leaf from Allen Short's C implementation of E (ecru) where he builds it as an extension type for Python -- allowing it to be bootstrapped off existing Python libraries...

    In an ideal case, the ideas would then get folded back into mainline Python -- but failing that, we would still have a Python-esque object-capability language that should be useful on its own...

    What do you think of this?

    --
    Thanks again for taking the time to share your thoughts, tav
  • tav · 9 months ago
    Mark, I've fixed up safelite.py and made the documentation in this article now only support the explicit version of Namespace(). Thanks again!