maranget / hevea

Hevea is a fast latex to html translator
http://hevea.inria.fr
Other
98 stars 12 forks source link

Unsafe /tmp usage in imagen #72

Open orlitzky opened 6 months ago

orlitzky commented 6 months ago

Hi, I (quite accidentally) noticed that the imagen program is using predictable paths under /tmp:

COM=/tmp/imagen-com.$$
TMPPNG=/tmp/imagen-tmp-png.$$

In particular, $COM is used to run code:

${GS} ${GSOPTS} -sOutputFile="| sh ${COM} > ${FINAL}" -

There are some well-known exploits that can take advantage of the code above. Basically, someone else on the machine can create those files before you do. Then he owns those files and can write malicious commands into them.

The use of the current PID in the filename helps a little bit, but ultimately PIDs are guessable, and all of them are known beforehand -- they're just sequential integers, after all. So in the end it's still pretty easy for someone to take over the temporary files that you want to use.

Fortunately there is a standard C function called mkstemp() that can create those files securely. Unfortunately, it's not easily available in POSIX shell script. The following trick can be used however:

posix_mktemp(){
    # Securely create a temporary file under ${TMPDIR} using the                     
    # template "tmpXXXXXX", and echo the result to stdout. This works                
    # around the absence of "mktemp" in the POSIX standard.                          
    printf 'mkstemp(template)' | m4 -D template="${TMPDIR:-/tmp}/tmpXXXXXX"
}

COM=$(posix_mktemp)
TMPPNG=$(posix_mktemp)

Since m4 is POSIX, and since it has an interface to the C mkstemp() function, we let m4 create the temporary directory instead. This avoids the security issues by using a name that is truly unguessable.

cspiel commented 6 months ago

In my experience it pays off to create a single temporary directory as "root" dir for all subsequent temporaries as soon as there are more than say one or two temporary files. Cleanup will be simpler as only one directory must be blown away on (whatever kind of) exit and maintenance will be simpler, too.

So, I'd like to suggest

IMAGEN_TMPROOT=$(posix_mktemp)
COM="$IMAGEN_TMPROOT/com"
TMPPNG="$IMAGEN_TMPROOT/png"

or something along that lines. Here follow up mkdir(1) calls are necessary, though.

Oh yeah, I almost forgot: speed! Only one invocation of m4(1). LOL.

orlitzky commented 6 months ago

In my experience it pays off to create a single temporary directory as "root" dir for all subsequent temporaries as soon as there are more than say one or two temporary files.

Maybe, but I don't know how to do that :P