Coder Social home page Coder Social logo

Comments (5)

ncoghlan avatar ncoghlan commented on July 21, 2024

Just illustrating one of the main reasons this approach counts as a "heavy handed runtime style hint" rather than an enforced security boundary:

>>> exec("print(dir())", {})
['__builtins__']
>>> code = """\
... for cls in __builtins__.__class__.mro()[-1].__subclasses__():
...         maybe_real_builtins = None
...         for name, attr in cls.__dict__.items():
...             try:
...                 maybe_real_builtins = attr.__globals__["__builtins__"]
...             except:
...                 continue
...             if maybe_real_builtins:
...                 print = maybe_real_builtins["print"]
...                 len = maybe_real_builtins["len"]
...                 print(len(maybe_real_builtins))
...                 break
...         if maybe_real_builtins:
...             break
... """
>>> limited_namespace = dict(__builtins__=None)
>>> exec(code, limited_namespace)
150

When you call exec, if you don't specify a builtin namespace, then Python automatically supplies the default one. However, if you do specify one (or explicitly set it to None), then that can still be used as a way of getting runtime access to object (purely via attribute accesses), which in turn grants access to all its subclasses, one of which will inevitably have a method implemented in Python (e.g. the import machinery), which will grant access to that module's globals, and hence to the real builtins.

However, this also shows that programmatically blocking access to the standard builtins isn't especially trivial to work around, so the dozen lines needed to do so provides a really strong hint to say "If you think you need to be doing this, Pipfile probably isn't the right tool for the task at hand"

from pipfile.

takluyver avatar takluyver commented on July 21, 2024

Reading the README, with group('development'): came as a doubly unpleasant surprise:

  • I don't like specifying metadata in executable files in general. #8 gives one reason why not - it's very hard to reliably modify scripts programmatically.
  • If we do use an executable script, I don't like the use of context managers as a way to group statements. Rather than functions that modify some invisible global state, why not build up global state visibly, e.g.:
requirements.extras['development'] = [
    package('nose'),
]

I like @ncoghlan's idea of strongly discouraging overly complex definitions, but I worry that anything that looks vaguely like a security boundary will lead people to trust these files inappropriately. It disguises execution as 'just parse this file'. Also, if you all but disallow code reuse through import, having an executable file doesn't seem so useful.

from pipfile.

ncoghlan avatar ncoghlan commented on July 21, 2024

As noted in #10 (comment) I'm now favouring resolving the imperative-vs-declarative question by offering an imperative Pipfile.in (that provides the full flexibility of normal Python code) that is combined with an automation-friendly declarative Pipfile format (where regeneration from Pipfile.in only modifies entries that were created from Pipfile.in in the first place).

That kind of approach should provide all of the advantages of both the imperative and declarative models, while the restrictive approach I suggest here would mainly leave us with the disadvantages of both models.

from pipfile.

pradyunsg avatar pradyunsg commented on July 21, 2024

@ncoghlan What are your thoughts on this now, given that #10 is resolved and #47 merged?

from pipfile.

ncoghlan avatar ncoghlan commented on July 21, 2024

The switch to a declarative file format resolves this concern, so closing the issue.

from pipfile.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.