Dear all.
Since Tcl9 is out there, it becomes time for working towards the NaviServer 5
release. The most recent version of NaviServer from the main branch works
nicely with the release of Tcl9 (for trying, you might consider the docker
image "gustafn/naviserver/latest-tcl9-bookworm” from
https://hub.docker.com/repository/docker/gustafn/naviserver/).
One of the open topics for the NaviServer 5 release is the following: The
function “ns_mktemp" exists in NaviServer since ages. The function is based on
the POSIX call mktemp() [1], which is unfortunately deprecated since a few
years. When compiling NaviServer, one sees messages like the following:
tclfile.c:255:51: warning: 'mktemp' is deprecated: This function is provided
for compatibility reasons only. Due to security concerns inherent in the
design of mktemp(3), it is highly recommended that you use mkstemp(3) instead.
[-Wdeprecated-declarations]
255 | Tcl_SetObjResult(interp, Tcl_NewStringObj(mktemp(buffer),
TCL_INDEX_NONE));
| ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/_stdlib.h:210:1:
note: 'mktemp' has been explicitly marked deprecated here
210 | __deprecated_msg("This function is provided for compatibility reasons
only. Due to security concerns inherent in the design of mktemp(3), it is
highly recommended that you use mkstemp(3) instead.")
| ^
Even worse, newer versions of OpenBSD produce warning messages whenever code is
linked containing calls to mktemp() [2]. So, there is no future for mktemp() in
NaviServer.
The problem with the C-level function mktemp() is that its usage leads to a
race condition, opening space to attacks. The problematic case happens when an
application generates a file name with the mktemp() function and then create a
file using this name. Unfortunately, this is not secure, because a different
process may create a file with this name in the time between the call to
mktemp() and the subsequent attempt to create the file by the first process. A
malicious user can predict the name of the temporary file, resulting in other
files being accessed, modified, corrupted, or deleted.
The recommended way is to combine the two steps and create the file in an
atomic operation (POSIX mkstemp() for files and mkdtemp() for directories).
These functions are used by Tcl "file tempfile" and by Tcl9 "file tempdir" and
in NaviServer 5 via "ns_mkdtemp".
However, there are many cases, where existing programs use "ns_mkstemp", which
cannot be replaced easily. When looking at OpenACS, I see 33 cases like
- the temporary name is passed to an external program (e.g. "tar", "zip", image
creation), or
- the temporary name is passed to a Tcl function expecting a filename (e.g.
"file copy").
So, dropping the support for "ns_mkstemp" fully is not a good option. Also,
providing a "home-cooked" version of "ns_mktemp" is not good either (both in
Tcl or in C), since technically speaking, this will not be better than the
original function having the same problems. Ignoring the compilation warning is
not good either, since sooner or later, the deprecated function will be removed.
What should we do?
- place "ns_mktemp" into an external module?
NaviServer will compile nicely, but applications like OpenACS
will have to load the module, making administration and migration
to NaviServer 5 less smooth.
- Call the safe function (e.g. mkstemp()) and delete the file, while
producing a depreciation message? This could also be done on the Tcl-level.
Other options? Opinions?
All the best
-g
[1] https://pubs.opengroup.org/onlinepubs/009695399/functions/mktemp.html
[1] https://man.openbsd.org/OpenBSD-7.5/mkstemp.3
_______________________________________________
naviserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/naviserver-devel