The only reasonable workaround I can think of is to first create a
temporary directory using mkdtemp(), then use a well-known name inside
that directory. But that has the same security implications AFAICT,
since another process can come and create the file / symlink first.
Regards
Antoine.
This plan LGTM.
Currently mkdir() is widely used in distutils, Sphinx, pip, setuptools,
virtualenv, and many other third-party projects, so it will take time to
fix all these places. But we should do this, because all this code
likely contains security flaws.
The fact that many projects, including well-maintained ones such Sphinx
or pip, use mktemp(), may be a hint that replacing it is not as easy as
the people writing the Python documentation seem to think.
Regards
Antoine.
I would prefer to keep tempfile.mktemp(), remove the deprecation, but
better explain the risk of race condition affecting security.
Le mar. 19 mars 2019 à 14:41, Chris Angelico <ros...@gmail.com> a écrit :
> Can't you create a NamedTemporaryFile and permit the other program to
> use it? I just tried that (with TiMidity, even though it's quite
> capable of just writing to stdout) and it worked fine.
When I write tests, I don't really care of security, but
NamedTemporaryFile caused me many troubles on Windows: you cannot
delete a file if it's still open in a another program. It's way more
convenient to use tempfile.mktemp().
O_EXCL, open(tmpname, "wx"), os.open(tmpname, os.O_CREAT | os.O_EXCL |
os.O_WRONLY), etc. can be used to get an error if the file already
exists.
I agree that for production code where security matters,
tempfile.mktemp() must be avoided. But I would prefer to keep it for
tests.
"with NamedTemporaryFile() as tmp: name = tmp.name" isn't a great
replacement for tempfile.mktemp(): it creates the file and it opens
it, whereas I only want a file name and be the first file to create
and open it.
Victor
2.3 -> 2.7, 3.0 -> 3.7, 13 releases and 17 years.
Maybe we could remove it with an official PendingDeprecationWarning.
Le 19/03/19 à 14:39, Antoine Pitrou a écrit :
> The fact that many projects, including well-maintained ones such Sphinx
> or pip, use mktemp(), may be a hint that replacing it is not as easy as
> the people writing the Python documentation seem to think.
What's the relation with the people writing the Python documentation?
The suggestion about the deprecation warning was proposed by Brett
Cannon, and Serhiy has proposed to deprecate this function with some
releases.
The final release for 3.8 is scheduled for October 2019
(PendingDeprecationWarning).
Maybe 3.9 will be released 18 months later (DeprecationWarning).
and maybe 3.10 or 4.0 will be released 18 months after 3.9.
so, from today to 3.9+ there are approximatively 43 months -> 3,5 years.
I think it's enough in term of time for the big projects to improve
their code.
Stéphane
If there are valid use cases for mktemp(), I recommend renaming
it to mkname_unsafe() or something equally obvious. Experience
(and the list of packages still using mktemp() posted here) shows
that just adding a warning to documentation is not enough. Users
often discover functions by experimentation or looking at examples
on the internet.
mktemp() is also unfortunately named, as it does not create a temp
file as implied. This can also add to the impression that it is the
proper function to use.
Adding a new function and following the deprecation process for the
old one should only be a minor inconvenience for existing users that
need it, should wake up existing users that should not use it in the
first place, and still allows it to be used for relevant use cases.
I believe for security reasons sometimes inconvenient changes like
this are necessary.
- Sebastian
"Deprecated" doesn't mean anything here. It's just a mention in the
documentation. It doesn't produce actual warnings when used. And for
good reason: there are valid use cases.
> so, from today to 3.9+ there are approximatively 43 months -> 3,5 years.
> I think it's enough in term of time for the big projects to improve
> their code.
Please explain how the "improvement" would look like. What is the
intended replacement for the use case I have explained, and how does it
improve on the statu quo?
And if there is an easy replacement, then how about re-implementing
mktemp() using that replacement, instead of removing it?
Regards
Antoine.
-1. Please don't remove tempfile.mktemp(). mktemp() is useful to
create a temporary *name*. All other tempfile functions create an
actual file and impose additional burden, for example by making the
file unaccessible by other processes. But sometimes all I want is a
temporary name that an *other* program will create / act on, not Python.
It's a very common use case when writing scripts.
The only reasonable workaround I can think of is to first create a
temporary directory using mkdtemp(), then use a well-known name inside
that directory. But that has the same security implications AFAICT,
since another process can come and create the file / symlink first.
mktemp() already does this, probably in a better way, including the
notion of prefix, suffix, and parent directory. Why should I have to
reimplement it myself?
Regards
Antoine.
I concur with others who think this should not be removed. It's used
in different stdlib and third party modules' test suites. I see
tempfile.mktemp() very similar to test.support.find_unused_port() and
os.path.exists/isfile/isdir functions: they are all subject to race
conditions but still they are widely used and have reason to exist
(practicality beats purity). I suggest turning the doc deprecation
into a note:: or warning::, so that extra visibility is maintained.
Because the use case is legitimate and many fs-related APIs such as
this one are inevitably racy, I lean more towards a note:: rather than
a warning:: though, and we could probably do the same for os.path.is*
functions.
@Sebastian
> If there are valid use cases for mktemp(), I recommend renaming
> it to mkname_unsafe() or something equally obvious.
I'm -1 about adding an alias (there should be one and preferably only
one way to do it). Also mkstemp() and mkdtemp() are somewhat poorly
named IMO, but I wouldn't add an alias for them either.
--
Giampaolo - http://grodola.blogspot.com
On top of that mktemp() tries exists() in a loop, diminishing the risk
of names collision.
--
Giampaolo - http://grodola.blogspot.com
But I had another thought: If I understand correctly, the exploitability
of mktemp() relies on the fact that between determining whether the
file exists and creation an attacker can create the file themselves.
Couldn't this problem be solved by generating a filename of sufficient
length using the secrets module? This way the filename should be
"unguessable" and safe.
- Sebastian
Am 19.03.19 um 17:23 schrieb Giampaolo Rodola':
> @Sebastian
>> If there are valid use cases for mktemp(), I recommend renaming
>> it to mkname_unsafe() or something equally obvious.
> I'm -1 about adding an alias (there should be one and preferably only
> one way to do it). Also mkstemp() and mkdtemp() are somewhat poorly
> named IMO, but I wouldn't add an alias for them either.
>
Just to clarify: I was not suggesting creating an alias, I was suggesting
renaming the function, but keeping the old name for a normal
deprecation cycle.
But I had another thought: If I understand correctly, the exploitability
of mktemp() relies on the fact that between determining whether the
file exists and creation an attacker can create the file themselves.
Couldn't this problem be solved by generating a filename of sufficient
length using the secrets module? This way the filename should be
"unguessable" and safe.
On Tue, 19 Mar 2019 at 17:47, Sebastian Rittau <sri...@rittau.biz> wrote:Am 19.03.19 um 17:23 schrieb Giampaolo Rodola':
> @Sebastian
>> If there are valid use cases for mktemp(), I recommend renaming
>> it to mkname_unsafe() or something equally obvious.
> I'm -1 about adding an alias (there should be one and preferably only
> one way to do it). Also mkstemp() and mkdtemp() are somewhat poorly
> named IMO, but I wouldn't add an alias for them either.
>
Just to clarify: I was not suggesting creating an alias, I was suggesting
renaming the function, but keeping the old name for a normal
deprecation cycle.
But I had another thought: If I understand correctly, the exploitability
of mktemp() relies on the fact that between determining whether the
file exists and creation an attacker can create the file themselves.
Couldn't this problem be solved by generating a filename of sufficient
length using the secrets module? This way the filename should be
"unguessable" and safe.Technically you cannot make it 100% safe, only less likely to occur.
And on a second thought (I retract :)) since this could be used in real apps other than tests (I was too focused on that) I think this should be a doc warning after all, not info. Doc may suggest to use mode=x when creating the file, in order to remove the security implications.
My fault!
Initially I searched mktemp, and have found usages in distutils, tests,
and few other modules in the stdlib. When I wrote the last message I
repeat the search on the wider set of Python sources, but for *mkdir*
instead of *mktemp*! Thank you for catching this mistake Paul.
Actually, seems mktemp is used exclusively in tests in third-party projects.
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/dev-python%2Bgarchive-30976%40googlegroups.com
Sorry, it was my mistake (searching mkdir instead of mktemp). mktemp is
only used in few tests in third-party projects.
That is not actually true. The important difference is that with
NamedTemporaryFile the file exists with appropriate access right (0600).
This denies access of that file to other users. With mktemp() no file is
created, so another user can "hijack" that name and cause programs to
write potentially privileged data into or read manipulated data from
that file.
- Sebastian
I'm not really convinced that mktemp() should be made "more secure".
To be clear: mktemp() is vulnerable by design. It's not a matter of
entropy. You can watch the /tmp directory using inotify and "discover"
immediately the "secret" filename, it doesn't depend on the amount of
entropy used to generate the filename. A function is either unsafe or
secure.
Why mktemp() only uses 8 characters? Well, I guess that humans like to
be able to copy manually (type) a filename :-)
Note: For the ones who didn't notice, "mktemp()" name comes from a
function with the same name in the libc.
http://man7.org/linux/man-pages/man3/mktemp.3.html
Victor
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/vstinner%40redhat.com
--
Night gathers, and now my watch begins. It shall not end until my death.
So far, I've seen these use cases:
1. File for the current process' private use
2. File/file name generated by the current process; written by another process, read by current one
3. File name generated by the current process; written by the current process, read by another one
And the following threats, three axes:
a. Processes run as other users
b. Processes run as the same user (or a user that otherwise automatically has access to all your files)
1. Accidental collision from a process that uses CREATE_NEW or equivalent
2. Accidental collision from a process that doesn't use CREATE_NEW or equivalent
3. Malicious code creating files at random
4. Malicious code actively monitoring file creation
-1. read
-2. write
E.g. for threat b-4), it's not safe to use named files for IPC at all, only case 1 can be secured (with exclusive open).
On 19.03.2019 16:03, Stéphane Wirtel wrote:
> Hi,
>
> Context: raise a warning or remove tempfile.mktemp()
> BPO: https://bugs.python.org/issue36309
>
> Since 2.3, this function is deprecated in the documentation, just in the
> documentation. In the code, there is a commented RuntimeWarning.
> Commented by Guido in 2002, because the warning was too annoying (and I
> understand ;-)).
>
> So, in this BPO, we start to discuss about the future of this function
> and Serhiy proposed to discuss on the Python-dev mailing list.
>
> Question: Should we drop it or add a (Pending)DeprecationWarning?
>
> Suggestion and timeline:
>
> 3.8, we raise a PendingDeprecationWarning
> * update the code
> * update the documentation
> * update the tests
> (check a PendingDeprecationWarning if sys.version_info == 3.8)
>
> 3.9, we change PendingDeprecationWarning to DeprecationWarning
> (check DeprecationWarning if sys.version_info == 3.9)
>
> 3.9+, we drop tempfile.mktemp()
>
> What do you suggest?
>
> Have a nice day and thank you for your feedback.
> _______________________________________________
> Python-Dev mailing list
> Pytho...@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/vano%40mail.mipt.ru
--
Regards,
Ivan