[LyX/2.5.x] Hardening case 00e - arbitrary command execution via index_command

Richard Kimberly Heck <[email protected]>
Newsgroups gmane.editors.lyx.cvs
Message-ID <[email protected]>
commit 476bf4dbb20c2669a683d162d377042e47358f6d
Author: Pavel Sanda <[email protected]>
Date:   Thu Jul 16 19:06:25 2026 +0200

    Hardening case 00e - arbitrary command execution via index_command
    
    A document-set \index_command was copied verbatim into the index-processor
    call on export, giving program substitution and <> redirection (file overwrite,
    same primitive as 00k), and/or code injection via metachars on windows.
    
    Fires on export.
    
    Tier 00 hotfix: accept only known index cmd, reject <> (+metas on win)
    Tier 01 DiD will land in master (canonical split, shared with 00d).
    
    Assisted-by: Claude Opus 4.8
---
 src/Converter.cpp | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/Converter.cpp b/src/Converter.cpp
index a162129f92..7aa5c00b3e 100644
--- a/src/Converter.cpp
+++ b/src/Converter.cpp
@@ -497,8 +497,39 @@ Converters::RetVal Converters::convert(Buffer const * buffer,
 			&& bp.encoding().package() == Encoding::japanese;
 		runparams.use_indices = bp.use_indices;
 		runparams.bibtex_command = bp.bibtexCommand(true);
-		runparams.index_command = (bp.index_command == "default") ?
-			string() : bp.index_command;
+
+		// Accept only programs from fixed known list
+		string accepted_index_cmd;
+		if (bp.index_command != "default" && !bp.index_command.empty()) {
+
+			// Block redirection (+ metas on Windows where it sinks to shell)
+#if defined(_WIN32)
+			static char const * const SUSPECT_CHARS = "<>" "&|()^%;";
+#else
+			static char const * const SUSPECT_CHARS = "<>";
+#endif
+			bool const has_suspect =
+				bp.index_command.find_first_of(SUSPECT_CHARS) != string::npos;
+			if (!has_suspect) {
+				string supplied_prog;
+				split(bp.index_command, supplied_prog, ' ');
+				for (auto const & alt : lyxrc.index_alternatives) {
+					string alt_prog;
+					split(alt, alt_prog, ' ');
+					if (!supplied_prog.empty()
+					    && supplied_prog == alt_prog) {
+						accepted_index_cmd = bp.index_command;
+						break;
+					}
+				}
+			}
+			if (accepted_index_cmd.empty())
+				LYXERR0("Document-supplied index command '"
+					<< bp.index_command << "' is not a recognised "
+					"index processor; falling back to default.");
+		}
+
+		runparams.index_command = accepted_index_cmd;
 		runparams.document_language = bp.language->lang();
 		// Some macros rely on font encoding
 		runparams.main_fontenc = bp.main_font_encoding();
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.