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: REPL tab-completion triggers code execution
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7, Python 3.6, Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Francisco Demartino, christian.heimes, louielu, serhiy.storchaka
Priority: normal Keywords:

Created on 2017-02-23 08:14 by Francisco Demartino, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
wat.py Francisco Demartino, 2017-02-23 08:14
Pull Requests
URL Status Linked Edit
PR 248 closed Francisco Demartino, 2017-02-23 09:32
Messages (12)
msg288420 - (view) Author: Francisco Demartino (Francisco Demartino) * Date: 2017-02-23 08:14
On the REPL, when autocompleting with the TAB key, getattr is called, potentially triggering code execution.

This took me by surprise. Until you press RETURN, it should be pretty safe to go around autocompleting with certainty that you won't run any code. But that might be just my opinion.

What do you think?
msg288421 - (view) Author: Louie Lu (louielu) * Date: 2017-02-23 08:27
I can reproduce the problem in Python 3.7.
msg288422 - (view) Author: Louie Lu (louielu) * Date: 2017-02-23 08:31
Could it be the problem from readline?
Using python 2 with readline trigger same behavior.
msg288424 - (view) Author: Francisco Demartino (Francisco Demartino) * Date: 2017-02-23 08:42
This branch (working on the PR) fixes it:

https://github.com/franciscod/cpython/tree/bpo-29630
msg288427 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-02-23 09:21
This is how Python works. Accessing an attribute (and even checking that the attribute exists) can trigger code executing.

Changes in https://github.com/franciscod/cpython/tree/bpo-29630 break autocompliting of proxy objects. And in any case it triggers code execution due to calling eval().

I think this is not a bug and changing current behavior can decrease usability.
msg288428 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-02-23 09:24
I agree with Serhiy. There is no way to safely inspect any Python object without triggering some dunder functions like __getattr__, __getattribute__ or __dir__.
msg288431 - (view) Author: Francisco Demartino (Francisco Demartino) * Date: 2017-02-23 09:36
I've updated that branch and made a pull request (https://github.com/python/cpython/pull/248)

I think this is a good compromise: inspect.getattr_static can tell if it's a property, and in that case we don't call getattr on it to prevent code execution on the completion. If it isn't a property, the current codepath is preserved.
msg288433 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-02-23 09:43
Your change is not backwards compatible and makes auto-completion less useful.
msg288435 - (view) Author: Francisco Demartino (Francisco Demartino) * Date: 2017-02-23 09:52
> There is no way to safely inspect any Python object without triggering some dunder functions like __getattr__, __getattribute__ or __dir__.

But somehow inspect.getattr_static can do it?

> Your change is not backwards compatible and makes auto-completion less useful.

Why is it less useful? The only change is not executing property getters when showing completion options. It's removing a surprising code execution before the newline is received.

Should CPython keep backwards compatibility of this execution-on-completion at the REPL?
msg288438 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-02-23 10:08
It is less useful because don't work with dynamic attributes (with __getattar__ and __getattribute__). And if executing property getters is an issue (I don't think it is), this change doesn't fix it completely.
msg288439 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2017-02-23 10:14
inspect.getattr_static *tries* to get attributes without triggering dunder methods. It's neither fully compatible to getattr() nor does it guarantee that no code is triggered. The function may or may not be secure.

Surprise or not surprise is a matter of perspective. I don't find it surprising.

It's incompatible because it gives different results:

>>> class Example:
...     @property
...     def example(self):
...          def func(): pass
...          return func
... 
>>> e = Example()
>>> e.exa<TAB>
>>> e.example(

with your patch, I'm getting:
>>> e.exa<TAB>
>>> e.example

Do you notice the difference?
msg288444 - (view) Author: Francisco Demartino (Francisco Demartino) * Date: 2017-02-23 12:44
Serhiy, Chris, thank you for your additional comments. They surely helped me understand why my solution to this "problem?" isn't that good (also I slept on it a bit and maybe that helped).

I still ponder for a way to get autocompletion while guarranteeing no code will run, but a) any getter code is meant to run in that way, and b) it would somehow need to know the result of running that code without running it (Tricky, huh?).

Thanks again for your patience. I feel enlightened :)
History
Date User Action Args
2022-04-11 14:58:43adminsetgithub: 73816
2017-02-23 12:44:37Francisco Demartinosetstatus: open -> closed

messages: + msg288444
2017-02-23 10:14:03christian.heimessetmessages: + msg288439
2017-02-23 10:08:18serhiy.storchakasetmessages: + msg288438
2017-02-23 09:52:54Francisco Demartinosetmessages: + msg288435
2017-02-23 09:43:21christian.heimessetmessages: + msg288433
2017-02-23 09:36:59Francisco Demartinosetmessages: + msg288431
2017-02-23 09:32:10Francisco Demartinosetstatus: pending -> open
pull_requests: + pull_request213
2017-02-23 09:24:18christian.heimessetstatus: open -> pending

type: behavior
versions: - Python 3.3, Python 3.4
nosy: + christian.heimes

messages: + msg288428
resolution: not a bug
stage: resolved
2017-02-23 09:21:37serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg288427
2017-02-23 08:42:00Francisco Demartinosetmessages: + msg288424
2017-02-23 08:31:43louielusetmessages: + msg288422
2017-02-23 08:27:57louielusetnosy: + louielu
messages: + msg288421
2017-02-23 08:14:27Francisco Demartinocreate