summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-10-04 10:07:55 -0700
committerGitHub <noreply@github.com>2022-10-04 10:07:55 -0700
commit90620490c04b6894d5a3f4214ecf5a10b41d25ec (patch)
treedcd4c98604ec34a1709fb96b6173e4ec1d0f0d58
parent246a044641388dfd5023cb4b8dbe5519cb41d943 (diff)
downloadcpython-git-90620490c04b6894d5a3f4214ecf5a10b41d25ec.tar.gz
[3.8] gh-97612: Fix shell injection in get-remote-certificate.py (GH-97613) (GH-97633)
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>
-rw-r--r--Misc/NEWS.d/next/Security/2022-09-28-12-10-57.gh-issue-97612.y6NvOQ.rst3
-rwxr-xr-xTools/scripts/get-remote-certificate.py25
2 files changed, 10 insertions, 18 deletions
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
index 0000000000..2f113492d4
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2022-09-28-12-10-57.gh-issue-97612.y6NvOQ.rst
@@ -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.
diff --git a/Tools/scripts/get-remote-certificate.py b/Tools/scripts/get-remote-certificate.py
index 38901286e1..68272fca83 100755
--- a/Tools/scripts/get-remote-certificate.py
+++ b/Tools/scripts/get-remote-certificate.py
@@ -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))