Subject: Re: bug#70440: [PATCH] Use -P switch when calling 'python-interpreter'

From: Augusto Stoffel <[email-masked]>
Date: Fri, 19 Apr 2024 08:08:43 +0200

On Fri, 19 Apr 2024 at 00:25, kobarity wrote:

> The -P switch is new, introduced in CPython 3.11, so I don't think it
> can be added unconditionally.  Furthermore, `python-interpreter' may
> not be CPython.  Isn't it enough to customize
> `python-interpreter-args'?

After sleeping on this, I recommend using -P anyway and simply failing
if the installed Python is too old.

The reason is that this has a security implication, similar to the
recent Org mode Latex preview situation.  Without -P the user is tacitly
trusting the contents of the current directory.  By tricking an user
into downloading a malicious file with an intentional name clash (say
via git pull), arbitrary code could in principle be executed on the
user's machine.

The -P switch completely removes this possibility, and conversely,
without -P there seems to be no reasonable way to make Python safe.

I've attached a new patch that informs the user why the commands failed
when Python is too old, which is good enough in my opinion.  Note also
that this change only affects the Python import management commands,
which is a very handy but by no means essential feature.

>From 2cca02440069a31546eff04c8cd6c00b171a85a2 Mon Sep 17 00:00:00 2001
From: Augusto Stoffel <[email-masked]>
Date: Wed, 17 Apr 2024 20:17:22 +0200
Subject: [PATCH] Use -P switch when calling 'python-interpreter'

This excludes the current directory from Python's module load path,
which can be unsafe.

* lisp/progmodes/python.el (python--list-imports, python--do-isort),
(python-fix-imports): Use -P switch
(python--list-imports-check-status): Warn about old Python versions
missing the -P switch.
---
 lisp/progmodes/python.el | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 85279d3e84b..304aa2d9d6e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -6744,9 +6744,9 @@ python--list-imports
 try:
     from isort import find_imports_in_stream, find_imports_in_paths
 except ModuleNotFoundError:
-    exit(2)
-except ImportError:
     exit(3)
+except ImportError:
+    exit(4)
 
 query, files, result = argv[1] or None, argv[2:], {}
 
@@ -6781,8 +6781,9 @@ python--list-imports-check-status
   (unless (eq 0 status)
     (let* ((details
             (cond
-             ((eq 2 status) " (maybe isort is missing?)")
-             ((eq 3 status) " (maybe isort version is older than 5.7.0?)")
+             ((eq 2 status) " (maybe Python version is older than 3.11?)")
+             ((eq 3 status) " (maybe isort is missing?)")
+             ((eq 4 status) " (maybe isort version is older than 5.7.0?)")
              (t "")))
            (msg
             (concat "%s exited with status %s" details)))
@@ -6805,7 +6806,7 @@ python--list-imports
                                   (append
                                    (split-string-shell-command
                                     python-interpreter-args)
-                                   `("-c" ,python--list-imports)
+                                   `("-Pc" ,python--list-imports)
                                     (list (or name "")))))
                        (with-current-buffer buffer
                          (apply #'call-process
@@ -6814,7 +6815,7 @@ python--list-imports
                                 (append
                                  (split-string-shell-command
                                   python-interpreter-args)
-                                 `("-c" ,python--list-imports)
+                                 `("-Pc" ,python--list-imports)
                                  (list (or name ""))
                                  (mapcar #'file-local-name source))))))
              lines)
@@ -6862,7 +6863,7 @@ python--do-isort
                                (append
                                  (split-string-shell-command
                                   python-interpreter-args)
-                                 '("-m" "isort" "-")
+                                 '("-Pm" "isort" "-")
                                  args)))
                 (tick (buffer-chars-modified-tick)))
             (unless (eq 0 status)
@@ -6940,7 +6941,7 @@ python-fix-imports
                   (append
                    (split-string-shell-command
                     python-interpreter-args)
-                   '("-m" "pyflakes"))))
+                   '("-Pm" "pyflakes"))))
         (goto-char (point-min))
         (when (looking-at-p ".* No module named pyflakes$")
           (error "%s couldn't find pyflakes" python-interpreter))
-- 
2.44.0