This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: security hole in eval()
Type: security Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: christian.heimes, cryptophoto, vstinner
Priority: normal Keywords:

Created on 2020-11-26 11:31 by cryptophoto, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (6)
msg381892 - (view) Author: Chris Drake (cryptophoto) Date: 2020-11-26 11:31
This should not work:-

python3.7 -c  'print(eval("().__class__.__base__.__subclasses__()[-1].__init__.__globals__",{"__builtins__": {}},{"__builtins__": {}}))'

and should be properly fixed.
msg381894 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2020-11-26 11:44
Would you care to explain why this should not work and how this behavior is in violation of the language specification?

It is perfectly valid expression. From a security perspective it may be an undesired feature. However Python does neither claim nor promise that eval is secure, see articel https://lwn.net/Articles/574215/ for more information on a failed attempt to sandbox Python. There is also ast.literal_eval() function, which provides limit evaluation of simple expressions.
msg381895 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-11-26 11:56
I suggest you to read https://python-security.readthedocs.io/security.html about the Python security model. In short, as soon as you let users to execute arbitrary Python code, they get a full access to the machine.

If you want to restrict access, you must run Python inside a restricted container (or any sandbox).
msg381898 - (view) Author: Chris Drake (cryptophoto) Date: 2020-11-26 12:55
The specification specifically allows for the restriction of access to globals via the second argument to eval.

While Christian and Victor make interesting, albeit suicidal, comments and references to other efforts, the fact remains that this is a violation of the standard, and is an exploitable security issue.

It's worth noting that the 1980's are long over now - people take security seriously these days, even when it's inconvenient.

The fix seems ridiculously trivial for what it's worth; introduce a flag that honors the intent of the second argument.
msg381900 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2020-11-26 13:31
Your assumption is incorrect. The eval() does not promise that default builtins cannot be access through other means. The behavior has been discussed several times and at great length over the past decade.
msg381903 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-11-26 15:01
> The specification specifically allows for the restriction of access to globals via the second argument to eval.

The Python language reference doesn't provide any warranty like that.
https://docs.python.org/dev/library/functions.html#eval

I close the issue as "not as bug".

All previous attempts to "sandbox" Python code in Python have failed. The correct way is to run Python in a sandbox. Not the opposite.

> https://lwn.net/Articles/574215/ 

This one was my attempt for example ;-)
History
Date User Action Args
2022-04-11 14:59:38adminsetgithub: 86638
2020-11-26 15:01:19vstinnersetstatus: open -> closed
resolution: not a bug
messages: + msg381903

stage: resolved
2020-11-26 13:31:44christian.heimessetmessages: + msg381900
2020-11-26 12:55:05cryptophotosetmessages: + msg381898
2020-11-26 11:56:48vstinnersetnosy: + vstinner
messages: + msg381895
2020-11-26 11:44:49christian.heimessetnosy: + christian.heimes
messages: + msg381894
2020-11-26 11:31:04cryptophotocreate