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
naviserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to