From ff1622afcf241ee4b8b2ff6057222020f27844bb Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Thu, 9 Jul 2020 11:31:34 -0700 Subject: [PATCH] zulip_tools: Replace deprecated mktemp call. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although mktemp is deprecated due to security issues, this is not a security issue. The security problems with mktemp happen when you open the resulting filename (without O_EXCL) in a publicly writable directory, because then someone else might have predicted the filename and created or symlinked or hardlinked something there between the mktemp and the open, causing you to write to a file you didn’t expect. Here we don’t open the resulting filename, we symlink to it. symlink will refuse to clobber an existing file, and we handle the error that arises from this case. This is the normal way to atomically create a symlink. We should still replace mktemp because it’s deprecated, but we can’t replace it with a function that creates the temporary file. Instead we build a random filename ourselves. Signed-off-by: Anders Kaseorg --- scripts/lib/zulip_tools.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/lib/zulip_tools.py b/scripts/lib/zulip_tools.py index 63ad61a686..1bed378976 100755 --- a/scripts/lib/zulip_tools.py +++ b/scripts/lib/zulip_tools.py @@ -8,12 +8,12 @@ import json import logging import os import pwd +import random import re import shlex import shutil import subprocess import sys -import tempfile import time import uuid from typing import Any, Dict, List, Sequence, Set @@ -40,10 +40,12 @@ MAGENTA = '\x1b[35m' CYAN = '\x1b[36m' def overwrite_symlink(src: str, dst: str) -> None: + dir, base = os.path.split(dst) while True: - tmp = tempfile.mktemp( - prefix='.' + os.path.basename(dst) + '.', - dir=os.path.dirname(dst)) + # Note: creating a temporary filename like this is not generally + # secure. It’s fine in this case because os.symlink refuses to + # overwrite an existing target; we handle the error and try again. + tmp = os.path.join(dir, ".{}.{:010x}".format(base, random.randrange(1 << 40))) try: os.symlink(src, tmp) except FileExistsError: