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.

Title: Documentation should warn about code injection from current working directory
Type: security Stage:
Components: Versions: Python 3.8, Python 3.7, Python 3.6, Python 3.4, Python 3.5, Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Gabriel Corona, eric.snow, ncoghlan, ronaldoussoren, vstinner, xtreak
Priority: normal Keywords:

Created on 2019-02-11 21:46 by Gabriel Corona, last changed 2022-04-11 14:59 by admin.

Messages (9)
msg335271 - (view) Author: Gabriel Corona (Gabriel Corona) Date: 2019-02-11 21:46
The CLI tools shipped in Debian python-rdflib-tools package can load modules from the current directory [1]:

    $ echo 'print("Something")' >
    $ rdf2dot
    INFO:rdflib:RDFLib Version: 4.2.2
    Reading from stdin as None...

This could be a security issue because an attacker could possibly exploit this behavior to execute arbitrary code.

This happens because these CLI tools are implemented as:

    exec /usr/bin/python -m $*

"python -m $module", "python -c $code" and "$command | python" prepend the current working directory in the Python path. The Python documentation [2] should probably warn about this. In Python 3, "-I" could be suggested to prevent the script/current directory to be added to the Python path. However, this flag has other effects.

The Python documentation suggests "python -m" commands at some places [3-5]: some form of warning at those places might be nice as well.

See the related behavior of Perl. Perl used to include "." in @INC but this was removed for security reasons [6].

msg335283 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-02-12 02:01
The change in behavior of Perl was discussed in
msg335302 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-02-12 13:06
Documentation is one thing. But I'm interested to discuss again (in 2019) the idea of changing the default behavior in Python 3.8 to enhance the "default" security.
msg335307 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2019-02-12 15:08
I don't know a good reason for including $PWD in sys.path for "python -m", I expect only scripts that run other scripts (such as might want the current behaviour and those can adjust to new behaviour.

For "python -c CMD" the current behaviour is easier to defend, this matches the behaviour w.r.t. sys.path of typing the command in an interactive session.

The behaviour for scripts (add the directory where the script is located to sys.path) is also easier to defend: that makes it easier to use scripts without installing stuf and without explicitly managing sys.path. 

I've used this in the past to split scripts into modules without installing modules in a global directory, but these days I tend to use virtual environment for that. I guess the usefulness of this behaviour depends on the type of user: the current behaviour is useful for more casual use of Python (which includes people learning python)
msg335310 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2019-02-12 15:46
+Nick (who may have some insight here)
msg335312 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-02-12 16:00
If someone wants to change the Python default behavior, a PEP will be required since it would be a major backward incompatible changes. A lot of details and use cases must be discussed and documented.
msg335315 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2019-02-12 16:02
related: issue #13475
msg335316 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2019-02-12 16:04
Note that I've asked Guido to comment about CWD in sys.path on issue #35969.
msg335705 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2019-02-16 17:47
Folks use "python -m myproject.mymodule" to run code that they're working on all the time - it's currently the only way to get sys.path right for cases like that (otherwise you're exposed to the double import trap, where you can get two copies of a submodule under different names).

We even use it to run CPython's own test suite as "./python -m test".

That said, over in I came up with a plausible migration path away from doing that implicitly - we'd just have to introduce a spelling for doing it explicitly instead, and relative imports give us a precedent for that.
Date User Action Args
2022-04-11 14:59:11adminsetgithub: 80152
2019-02-16 17:47:39ncoghlansetmessages: + msg335705
2019-02-12 16:04:42eric.snowsetmessages: + msg335316
2019-02-12 16:02:59eric.snowsetmessages: + msg335315
2019-02-12 16:00:32vstinnersetmessages: + msg335312
2019-02-12 15:46:19eric.snowsetnosy: + eric.snow, ncoghlan
messages: + msg335310
2019-02-12 15:08:07ronaldoussorensetnosy: + ronaldoussoren
messages: + msg335307
2019-02-12 13:06:52vstinnersetmessages: + msg335302
2019-02-12 02:01:31xtreaksetnosy: + vstinner, xtreak
messages: + msg335283
2019-02-11 21:46:00Gabriel Coronacreate