summaryrefslogtreecommitdiff
path: root/paramiko/pkey.py
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2022-02-25 14:50:42 -0500
committerJeff Forcier <jeff@bitprophet.org>2022-03-11 23:18:48 -0500
commit4c491e299c9b800358b16fa4886d8d94f45abe2e (patch)
treec393f585cde6194489375e4568fae43dd49766c2 /paramiko/pkey.py
parentaa3cc6fa3e9f1df72d4ffd2d5fc02ae734a6cba4 (diff)
downloadparamiko-4c491e299c9b800358b16fa4886d8d94f45abe2e.tar.gz
Fix CVE re: PKey.write_private_key chmod race
CVE-2022-24302 (see changelog for link)
Diffstat (limited to 'paramiko/pkey.py')
-rw-r--r--paramiko/pkey.py12
1 files changed, 11 insertions, 1 deletions
diff --git a/paramiko/pkey.py b/paramiko/pkey.py
index 7865a6ea..67945261 100644
--- a/paramiko/pkey.py
+++ b/paramiko/pkey.py
@@ -558,7 +558,17 @@ class PKey(object):
:raises: ``IOError`` -- if there was an error writing the file.
"""
- with open(filename, "w") as f:
+ # Ensure that we create new key files directly with a user-only mode,
+ # instead of opening, writing, then chmodding, which leaves us open to
+ # CVE-2022-24302.
+ # NOTE: O_TRUNC is a noop on new files, and O_CREAT is a noop on
+ # existing files, so using all 3 in both cases is fine. Ditto the use
+ # of the 'mode' argument; it should be safe to give even for existing
+ # files (though it will not act like a chmod in that case).
+ kwargs = dict(flags=os.O_WRONLY | os.O_TRUNC | os.O_CREAT, mode=o600)
+ # NOTE: yea, you still gotta inform the FLO that it is in "write" mode
+ with os.fdopen(os.open(filename, **kwargs), mode="w") as f:
+ # TODO 3.0: remove the now redundant chmod
os.chmod(filename, o600)
self._write_private_key(f, key, format, password=password)