classification
Title: collections.namedtuple does questionable things when passed questionable arguments
Type: Stage:
Components: Library (Lib) Versions: Python 3.5, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: Kevin.Norris, haypo, python-dev, rhettinger
Priority: normal Keywords:

Created on 2014-06-24 03:52 by Kevin.Norris, last changed 2014-06-25 01:13 by python-dev. This issue is now closed.

Messages (7)
msg221394 - (view) Author: Kevin Norris (Kevin.Norris) Date: 2014-06-24 03:52
Code such as this:

    class Foo:
        def __str__(self):
            # Perhaps this value comes from user input, or
            # some other unsafe source
            return something_untrusted
        def isidentifier(self):
            # Perhaps it returns false in some esoteric case
            # which we don't care about. Assume developer
            # did not know about str.isidentifier() and
            # the name clash is accidental.
            return True

    collections.namedtuple(Foo(), ())

...may result in arbitrary code execution.  Since the collections documentation does not say that such things can happen, this could result in highly obscure security vulnerabilities.  The easiest fix is to simply call str() on the typename argument to namedtuple(), as is currently done with the field_names argument.  But IMHO this is like cleaning up an SQL injection with string sanitizing, instead of just switching to prepared statements.  The "switch to prepared statements" route is conveniently available as a rejected patch for issue 3974.

The above code will not work as such in Python 2.7, but more elaborate shenanigans can fool the sanitizing in that version as well.

This issue was originally reported on security@python.org, where I was advised to file a bug report normally.
msg221416 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-24 07:25
IMO we should rewrite the implementation of namedtuple to avoid completly eval(). But there is the problem of the _source attribute: #19640.
msg221492 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014-06-24 20:18
ISTM that in order to run you code, a person already has to have the ability to run arbitrary code.

The purpose of the existing checks was to support the use-case where the field names are taken from the header line of CSV files.

I would be happy to add a test for exact string inputs but will not throw-out the current design which has a number of advantages including the ability to keep just the generated code and throw-away the factory function itself.
msg221496 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-24 20:49
New changeset 30063f97a44d by Raymond Hettinger in branch '2.7':
Issue 21832:  Require named tuple inputs to be exact strings
http://hg.python.org/cpython/rev/30063f97a44d
msg221497 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2014-06-24 20:50
I'll add the 3.4 and 3.5 as well plus a Misc/NEWS item shortly.
msg221515 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-25 01:08
New changeset c238d2899d47 by Raymond Hettinger in branch '3.4':
Issue 21832:  Require named tuple inputs to be exact strings
http://hg.python.org/cpython/rev/c238d2899d47

New changeset 5c60dd518182 by Raymond Hettinger in branch '3.4':
Issue 21832:  Require named tuple inputs to be exact strings
http://hg.python.org/cpython/rev/5c60dd518182
msg221516 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-25 01:13
New changeset 958e8bebda6d by Raymond Hettinger in branch '3.4':
Add news entry for #21832
http://hg.python.org/cpython/rev/958e8bebda6d
History
Date User Action Args
2014-06-25 01:13:39python-devsetmessages: + msg221516
2014-06-25 01:08:50python-devsetmessages: + msg221515
2014-06-24 20:50:44rhettingersetstatus: open -> closed
resolution: fixed
messages: + msg221497
2014-06-24 20:49:38python-devsetnosy: + python-dev
messages: + msg221496
2014-06-24 20:18:48rhettingersetmessages: + msg221492
2014-06-24 20:12:35rhettingersetversions: - Python 3.1, Python 3.2, Python 3.3
2014-06-24 20:11:35rhettingersetassignee: rhettinger
2014-06-24 07:25:09hayposetnosy: + haypo
messages: + msg221416
2014-06-24 03:58:58benjamin.petersonsetnosy: + rhettinger
2014-06-24 03:52:23Kevin.Norriscreate