]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.8] gh-97612: Fix shell injection in get-remote-certificate.py (GH-97613) (GH-97633)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 4 Oct 2022 17:07:55 +0000 (10:07 -0700)
committerGitHub <noreply@github.com>
Tue, 4 Oct 2022 17:07:55 +0000 (10:07 -0700)
Fix a shell code injection vulnerability in the
get-remote-certificate.py example script. The script no longer uses a
shell to run "openssl" commands. Issue reported and initial fix by
Caleb Shortt.

Remove the Windows code path to send "quit" on stdin to the "openssl
s_client" command: use DEVNULL on all platforms instead.

Co-authored-by: Caleb Shortt <caleb@rgauge.com>
(cherry picked from commit 83a0f44ffd8b398673ae56c310cf5768d359c341)

Co-authored-by: Victor Stinner <vstinner@python.org>
Misc/NEWS.d/next/Security/2022-09-28-12-10-57.gh-issue-97612.y6NvOQ.rst [new file with mode: 0644]
Tools/scripts/get-remote-certificate.py

diff --git a/Misc/NEWS.d/next/Security/2022-09-28-12-10-57.gh-issue-97612.y6NvOQ.rst b/Misc/NEWS.d/next/Security/2022-09-28-12-10-57.gh-issue-97612.y6NvOQ.rst
new file mode 100644 (file)
index 0000000..2f11349
--- /dev/null
@@ -0,0 +1,3 @@
+Fix a shell code injection vulnerability in the ``get-remote-certificate.py``
+example script. The script no longer uses a shell to run ``openssl`` commands.
+Issue reported and initial fix by Caleb Shortt. Patch by Victor Stinner.
index 38901286e19ad1aa26f8f8b73ec36267ed1e7822..68272fca83fe27b61d5dafef3c21c2125a7b29c6 100755 (executable)
@@ -15,8 +15,8 @@ import tempfile
 def fetch_server_certificate (host, port):
 
     def subproc(cmd):
-        from subprocess import Popen, PIPE, STDOUT
-        proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True)
+        from subprocess import Popen, PIPE, STDOUT, DEVNULL
+        proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, stdin=DEVNULL)
         status = proc.wait()
         output = proc.stdout.read()
         return status, output
@@ -33,8 +33,8 @@ def fetch_server_certificate (host, port):
                 fp.write(m.group(1) + b"\n")
             try:
                 tn2 = (outfile or tempfile.mktemp())
-                status, output = subproc(r'openssl x509 -in "%s" -out "%s"' %
-                                         (tn, tn2))
+                cmd = ['openssl', 'x509', '-in', tn, '-out', tn2]
+                status, output = subproc(cmd)
                 if status != 0:
                     raise RuntimeError('OpenSSL x509 failed with status %s and '
                                        'output: %r' % (status, output))
@@ -45,20 +45,9 @@ def fetch_server_certificate (host, port):
             finally:
                 os.unlink(tn)
 
-    if sys.platform.startswith("win"):
-        tfile = tempfile.mktemp()
-        with open(tfile, "w") as fp:
-            fp.write("quit\n")
-        try:
-            status, output = subproc(
-                'openssl s_client -connect "%s:%s" -showcerts < "%s"' %
-                (host, port, tfile))
-        finally:
-            os.unlink(tfile)
-    else:
-        status, output = subproc(
-            'openssl s_client -connect "%s:%s" -showcerts < /dev/null' %
-            (host, port))
+    cmd = ['openssl', 's_client', '-connect', '%s:%s' % (host, port), '-showcerts']
+    status, output = subproc(cmd)
+
     if status != 0:
         raise RuntimeError('OpenSSL connect failed with status %s and '
                            'output: %r' % (status, output))