Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <aoMVr9PASwnyGqg9@ucw.cz>
Date: Mon, 17 Aug 2026 16:07:43 +0200
From: Pavel Sanda <sanda@....org>
To: oss-security@...ts.openwall.com
Subject: LyX security advisory

Hello,

Multiple vulnerabilities were identified in the LyX document processor (www.lyx.org)
and associated tools from the TeXLive ecosystem (biber/xindy/xindex).

Quick Summary:
 1) If you are on a rolling-type of package distribution it is best to
   adopt newly released LyX 2.5.2, containing all hotfixes listed below.
   Although safe without it, upgrading biber to version 2.22 will avoid
   newly implemented authorization prompts.

 2) If you are on more conservative distro/channel we are offering backporting
   patchsets for older 2.5/2.4/2.3/2.2 stable series (but we are not going to
   offer new binaries except for 2.5.2). See 2.x-backport.patch files.
   Although safe without it, we suggest backporting the biber dev-branch fixes
   47ccd83 / 30c2a10 / 584a1e3 + 74252e6 into your biber (2.XX) AND relaxing the
   version check in src/LaTeX.cpp (the last two fields are the required
   major, minor version):
   -	{ "biber", false, "--version", "version:\\s*([0-9]+)\\.([0-9]+)", 2, 22 },
   +	{ "biber", false, "--version", "version:\\s*([0-9]+)\\.([0-9]+)", 2, XX },
   That will avoid newly implemented authorization prompts, which would hit large
   fraction of userbase otherwise.



In the section below there is a list of so far identified issues and their fixes.
I have exploits available upon request for distro responders if testing is
needed, but do not plan to publicly release them. I can share more detailed
notes on each issue in case someone needs it for backporting work.

I did not request any CVEs. If anyone finds it useful to assign, a single
coordinated set noted back in this thread would let everyone reference the
same identifiers.

2.5.2 tarballs are now on ftp.lyx.org. The patchsets are attached to this email;
they will also land on their git.lyx.org branches shortly.


The issues
----------
All are triggered by opening/importing/exporting a maliciously crafted LyX
document (network-deliverable: a zip, an email attachment, a shared folder).
Unless noted, the result is arbitrary command execution with the user's
privileges. No shell-escape / \write18 is required.

  Load-triggered (fire on document open/import -- worst case):
  -----------------------------------------------------------
    00a kpsewhich           a shell-metacharacter filename (e.g. a bibliography
                            database name) is concatenated into a
                            "kpsewhich <name>" shell command; also on export.
    00b lyx2lyx             filenames are spliced as a shell string into the
                            lyx2lyx converter invocation run on open.
    00c graphics-extension  a graphics inset's filename extension carries shell
                            metacharacters into an os.system() in LyX's
                            generated image-conversion script (the file must
                            exist on disk).
    00h import-path         the document's own filename reaches shipped conversion
                            helpers; the name enters on open/import and
                            fires on a later export. Fix folded into 00i.

  Export / View-PDF triggered (fire on a user export action):
  ----------------------------------------------------------
    00d bibtex_command      the document sets \bibtex_command to an arbitrary
                            program or with shell metacharacters; reaches the
                            preview pipeline (shell=True) and the export bibtex
                            call.
    00e index_command       same, for \index_command (arbitrary index processor
                            or "<" ">" redirection).
    00g mangled-filename    a hostile graphics filename's bytes survive
                            mangledFileName into re-shelling helper scripts.
    00i convert-pdf         a hostile .lyx basename with backticks hits command
                            substitution inside "..." quoting in buffer-basename
                            helpers (convert_pdf.py, ...).
    00k paperdim            raw \paperwidth / \paperheight bytes reach a parsecmd
                            ">" redirection -> arbitrary file truncate/overwrite
                            (file write, not command execution).

  Layer-2 mitigation (a new consent authorization gate for unpatched external tools):
  ----------------------------------------------------------------------------------
    00de processing gate    prompts before running a code-capable bib/index tool
                            (biber/xindy/xindex) on an untrusted document,
                            because those tools execute document-embedded code
                            even with the default command (biber sourcemap /ee,
                            xindy -M backtick, xindex CWD .lua). The real fixes
                            are upstream (biber 2.22, xindex 1.07); the gate is 
			    LyX's interim guard.
    00de-2 xindex check     xindex-only add-on (version gate + --restricted +
                            CWD jail) that stacks on the gate.
			    Scheduled for LyX 2.5.2.


Per-branch fix status (Tier 00)
=============================================

For each fixed issue, this grid shows which LyX release lines carry the fix.

Legend
------
  Y         fixed; exploit and fix manually confirmed on this line
  DiD       shipped as defence-in-depth: the fix applies and was reviewed,
            but there is no confirmed proof-of-concept on this line.
  WONTFIX   not fixed on this line (residual exposure noted below)

  Trigger:  "open"   = fires on document open / import
            "export" = fires on export or View-PDF (a user action)
            "exec"   = arbitrary command execution
            "write"  = arbitrary file write / truncate

  master    = development line (next major future release 2.6);
              Tier >=01 DiD fixes land there after the maintenance-release rollout.


  Item                         Trigger              master 2.5.2  2.5.x  2.4.x  2.3.x  2.2.x
  ---------------------------  -------------------  ------ -----  -----  -----  -----  -----
  00a kpsewhich RCE            open/export -> exec  Y      Y      Y      Y      Y      Y
  00b lyx2lyx RCE              open -> exec         Y      Y      Y      Y      Y      Y  [1]
  00c graphics-extension RCE   open -> exec         Y      Y      Y      Y      Y      Y
  00d bibtex_command RCE       open/export -> exec  Y      Y [7]  Y      Y      Y      WONTFIX [2]
  00e index_command RCE        export -> exec       Y      Y [7]  Y      Y      Y      WONTFIX [3]
  00g mangled-filename RCE     export -> exec       Y      Y      Y      Y      Y      Y
  00h import-path RCE          open/import -> exec  Y      Y      Y      Y      DiD    DiD [4] [8]
  00i convert-pdf RCE          export -> exec       Y      Y      Y      Y      Y      Y
  00k paperdim file-truncate   export -> write      Y      Y      Y      Y      Y      Y
  00de processing consent gate export -> exec       Y [5]  Y      Y      Y      Y      WONTFIX [6]
  00de-2 xindex version check  export -> exec       Y      Y      WONTFIX WONTFIX WONTFIX WONTFIX

Notes
-----
  [1] 2.2.x uses a slightly adapted form of the same fix.
  [2] 2.2.x: the bibtex_command whitelist fix is not backported. The consent
      prompt (below) that covers the underlying external-processor class is
      infeasible on 2.2.x, so that class stays open there regardless; the
      residual direct vector is a limited, attacker-constrained
      output-redirection primitive.
  [3] 2.2.x: the index_command whitelist fix is not backported; the
      index-processor export RCE remains on 2.2.x.
  [4] 2.3.x / 2.2.x: fix reviewed and applied defensively. The exact pre-2.4
      exploit does not reproduce, so it ships without a confirmed
      proof-of-concept on those lines -- but a working exploit is likely
      to exist there (cold code analysis found additional live sinks of
      the same class). Treat these lines as vulnerable, not clear.
  [5] On master (next feature release) the consent prompt will be present but OFF
      by default -- that line targets a fixed toolchain; an opt-in preference
      is retained.
  [6] 2.2.x lacks the session-trust framework the consent prompt hooks into,
      so the prompt is not feasible there.
  [7] 2.5.2 additionally carries the Windows metacharacter widen for 00d/00e. 
      The backported lines (2.5 / 2.4 / 2.3) ship the POSIX filter
      only -- we deliver no Windows binaries for those.
  [8] 00h and 00i share a single fix: hardening makeLatexName()'s allowed
      character set (00i-wide) strips the shell/cmd metacharacters at the
      source, closing both the convert-pdf (00i) and import-path (00h)
      sinks. There is therefore no separate 00h patch.

Note: the shell-escape hardening was intentionally not changed -- LyX follows
the host TeX configuration (restricted by default on all mainstream
distributions), which already refuses unconstrained \write18.


External tools (Tier EXT) - biber / xindy / xindex
==================================================

The processors behind the 00de consent gate run document-influenced code
with their default/whitelisted command. The gate is LyX's interim guard; the
real fixes are upstream, shipped through the tools' own channels. 

There won't be separate upstream announcements for the issues below. They gain
their leverage mainly from the automatic processing pipeline of LyX, which runs
these tools without user watching the details.


biber (Perl)
------------
  Issue    Biber runs document-controlled Perl on the default biblatex path,
           via three sinks: sourcemap /ee (ireplace), eval "require $package"
           and a sortfield eval. The sourcemap payload rides in the .bcf that
           biblatex writes from a \DeclareSourcemap preamble (no planted file),
           or in a CWD biber.conf biber auto-loads.
  Note     Not strictly a .lyx issue - a crafted .tex compiled through biber
           triggers it (true of xindy/xindex too).
  Fixes    Upstream was contacted and shipped fixes in biber 2.22 (all three sinks).
  Commits  github.com/plk/biber, branch dev (landed 2026-06-27..29):
             sourcemap /ee   47ccd83187  Utils.pm
             require         30c2a10fd1  Biber.pm, Constants.pm
             sortfield eval  584a1e3729 + 74252e608e  Internals.pm (both needed)
  Backport The three sink functions are byte-identical across v2.14-v2.21, so
           the commits graft onto any shipped version with only line offsets.
  LyX      2.5.2 and backports shipping the 00de gate relax the authorization
           prompts if biber >= 2.22 detected.
           If the biber fix is backported, please lower LyX's version threshold,
           see the diff in TL;DR.

xindy / texindy (Perl)
----------------------
  Issue    The -M module value is interpolated into a Perl backtick
           (`kpsewhich ... $module`) unquoted -> shell injection.
  Note     Absent from the frozen CTAN upstream; added downstream by a
           kpsewhich texmf-tree lookup. 
  TeX Live utils/xindy .../xindy.in (TLpatches/patch-01-xindy-script).
           Guarded form - only separator-free names reach the shell.
  Fixes    TL upstream was contacted and shipped the fix in TL's repo as r79990.
  LyX      no version-based relaxation, as no reliable version feedback exists.

xindex (texlua)
---------------
  Issue    xindex requires a CWD xindex-cfg.lua, executing arbitrary Lua.
           This is part of xindex's intended design, but opens a hole in
           LyX automatic processing.
  Fixes    Upstream was contacted and agreed to implement --restricted
           mode of processing (chdir-away jail on require / kpse.find_file).
           It shipped in xindex 1.07 via normal TeX Live / CTAN update.
  LyX      2.5.2 shipping the 00de gate relaxes the authorization prompts
           via 00de-2 if xindex >= 1.07 detected. 2.5/4/3 gates keep prompting.

View attachment "00a-kpsewhich.patch" of type "text/x-diff" (1736 bytes)

View attachment "00b-lyx2lyx.patch" of type "text/x-diff" (1865 bytes)

View attachment "00c-extension.patch" of type "text/x-diff" (1920 bytes)

View attachment "00d-bibtex-fix.patch" of type "text/x-diff" (2970 bytes)

View attachment "00e-index-fix.patch" of type "text/x-diff" (2455 bytes)

View attachment "00g-mangling_fix.patch" of type "text/x-diff" (3019 bytes)

View attachment "00i-wide.patch" of type "text/x-diff" (3002 bytes)

View attachment "00k-paperdim-validate.patch" of type "text/x-diff" (1351 bytes)

View attachment "00de-processing_gate.patch" of type "text/x-diff" (9919 bytes)

View attachment "00de-2-xindex-version-check.patch" of type "text/x-diff" (2988 bytes)

View attachment "2.2-backport.patch" of type "text/x-diff" (7368 bytes)

View attachment "2.3-backport.patch" of type "text/x-diff" (19780 bytes)

View attachment "2.4-backport.patch" of type "text/x-diff" (20632 bytes)

View attachment "2.5-backport.patch" of type "text/x-diff" (20711 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.