commit f3a89bd504443a5fd72dd9bb0cc487cfec010370
Author: Pavel Sanda <[email protected]>
Date: Thu Jun 4 13:20:02 2026 +0200
Hardening case 00b - arbitrary command execution via lyx2lyx invocation
convertLyXFormat() builds the lyx2lyx command as a shell string and passes
the filenames through quoteName(), which leaves active characters alive.
Crafted filename on an old-format .lyx injects arbitrary commands.
Fires on .lyx load (old-format file needing conversion).
Tier 00 hotfix: single-quote the filename args on POSIX, keep quoteName on
Windows.
Tier 01 DiD will land in master (argv-form lyx2lyx).
Assisted-by: Claude Opus 4.7
---
src/Buffer.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 2c8cf086c9..c17ff1f76a 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1413,12 +1413,22 @@ Buffer::ReadStatus Buffer::convertLyXFormat(FileName
const & fn,
// Run lyx2lyx:
// $python$ "$lyx2lyx$" -t $LYX_FORMAT$ -o "$tempfile$" "$filetoread$"
+
+ // guard against command expansion in filename strings on linux,
+ // keep " on windows
+ auto sh_quote = [](string const & s) -> string {
+#ifdef _WIN32
+ return quoteName(s);
+#else
+ return '\'' + subst(s, "'", "'\\''") + '\'';
+#endif
+ };
ostringstream command;
command << os::python()
- << ' ' << quoteName(lyx2lyx.toFilesystemEncoding())
+ << ' ' << sh_quote(lyx2lyx.toFilesystemEncoding())
<< " -t " << convert<string>(LYX_FORMAT)
- << " -o " << quoteName(tmpfile.toSafeFilesystemEncoding())
- << ' ' << quoteName(fn.toSafeFilesystemEncoding());
+ << " -o " << sh_quote(tmpfile.toSafeFilesystemEncoding())
+ << ' ' << sh_quote(fn.toSafeFilesystemEncoding());
string const command_str = command.str();
LYXERR(Debug::INFO, "Running '" << command_str << '\'');
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs