last patch attached.

    T.

On 06/11/2016 20:56, LyX Ticket Tracker wrote:
#10481: Hardening LyX against potential misuse
-------------------------+--------------------------
  Reporter:  t.cucinotta  |       Owner:  lasgouttes
      Type:  enhancement  |      Status:  new
  Priority:  highest      |   Milestone:
Component:  general      |     Version:  unspecified
  Severity:  major        |  Resolution:
  Keywords:               |
-------------------------+--------------------------

Comment (by t.cucinotta):

  Just fixed minor things and the wording in the attached .2.patch file,
  however there's the major issue that in GraphicsConverter there's no info
  whatsoever about buffer name, so it won't be possible to have the "yes,
  don't ask for the doc" option in that case...., that case being display
  on-screen, which is probably the most common/needed (the one that works ok
  is when you export to PDF or other formats).
  Tried to add the missing context in a separate patch, but got to nothing
  but ... segfaults!


commit c5c02d37
Author: Tommaso Cucinotta <tomm...@lyx.org>
Date:   Sat Nov 5 01:00:44 2016 +0100

    Add needauth option to converters that need explicit user authorization before being run.
    
    Addressing #10481.
    
    Converters marked with the new "needauth" option won't be run unless
    the user gives explicit authorization, which is asked on-demand when
    the converter is about to be run (question is not asked if the file is
    cached and the converter is not needed).
    
    The user prompt has a 3rd button (yes to all for document) so that
    he/she's not prompted again for the same converter over the same document
    (identified through buffer->filePath()).

diff --git a/lib/configure.py b/lib/configure.py
index 09d053e9..705aed6c 100644
--- a/lib/configure.py
+++ b/lib/configure.py
@@ -749,8 +749,8 @@ def checkConverterEntries():
         rc_entry = [r'''\converter latex      lyx        "%% -f $$i $$o"	""
 \converter latexclipboard lyx        "%% -fixedenc utf8 -f $$i $$o"	""
 \converter literate   lyx        "%% -n -m noweb -f $$i $$o"	""
-\converter sweave   lyx        "%% -n -m sweave -f $$i $$o"	""
-\converter knitr   lyx        "%% -n -m knitr -f $$i $$o"	""'''], not_found = 'tex2lyx')
+\converter sweave   lyx        "%% -n -m sweave -f $$i $$o"	"needauth"
+\converter knitr   lyx        "%% -n -m knitr -f $$i $$o"	"needauth"'''], not_found = 'tex2lyx')
     if path == '':
         logger.warning("Failed to find tex2lyx on your system.")
 
@@ -763,24 +763,24 @@ def checkConverterEntries():
 \converter literate   dviluatex     "%%"	""'''])
     #
     checkProg('a Sweave -> LaTeX converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxsweave.R $$p$$i $$p$$o $$e $$r'],
-        rc_entry = [r'''\converter sweave   latex      "%%"	""
-\converter sweave   pdflatex   "%%"	""
-\converter sweave   xetex      "%%"	""
-\converter sweave   luatex     "%%"	""
-\converter sweave   dviluatex  "%%"	""'''])
+        rc_entry = [r'''\converter sweave   latex      "%%"	"needauth"
+\converter sweave   pdflatex   "%%"	"needauth"
+\converter sweave   xetex      "%%"	"needauth"
+\converter sweave   luatex     "%%"	"needauth"
+\converter sweave   dviluatex  "%%"	"needauth"'''])
     #
     checkProg('a knitr -> LaTeX converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxknitr.R $$p$$i $$p$$o $$e $$r'],
-        rc_entry = [r'''\converter knitr   latex      "%%"	""
-\converter knitr   pdflatex   "%%"	""
-\converter knitr   xetex      "%%"	""
-\converter knitr   luatex     "%%"	""
-\converter knitr   dviluatex  "%%"	""'''])
+        rc_entry = [r'''\converter knitr   latex      "%%"	"needauth"
+\converter knitr   pdflatex   "%%"	"needauth"
+\converter knitr   xetex      "%%"	"needauth"
+\converter knitr   luatex     "%%"	"needauth"
+\converter knitr   dviluatex  "%%"	"needauth"'''])
     #
     checkProg('a Sweave -> R/S code converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxstangle.R $$i $$e $$r'], 
-        rc_entry = [ r'\converter sweave      r      "%%"    ""' ])
+        rc_entry = [ r'\converter sweave      r      "%%"    "needauth"' ])
     #
     checkProg('a knitr -> R/S code converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxknitr.R $$p$$i $$p$$o $$e $$r tangle'],
-        rc_entry = [ r'\converter knitr      r      "%%"    ""' ])
+        rc_entry = [ r'\converter knitr      r      "%%"    "needauth"' ])
     #
     checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex',
         'htmltolatex -input $$i -output $$o', 'htmltolatex.jar -input $$i -output $$o'],
diff --git a/src/Converter.cpp b/src/Converter.cpp
index 58e486e6..02631ca4 100644
--- a/src/Converter.cpp
+++ b/src/Converter.cpp
@@ -100,7 +100,7 @@ Converter::Converter(string const & f, string const & t,
 		     string const & c, string const & l)
 	: from_(f), to_(t), command_(c), flags_(l),
 	  From_(0), To_(0), latex_(false), xml_(false),
-	  need_aux_(false), nice_(false)
+	  need_aux_(false), nice_(false), need_auth_(false)
 {}
 
 
@@ -128,6 +128,8 @@ void Converter::readFlags()
 			parselog_ = flag_value;
 		else if (flag_name == "nice")
 			nice_ = true;
+		else if (flag_name == "needauth")
+			need_auth_ = true;
 	}
 	if (!result_dir_.empty() && result_file_.empty())
 		result_file_ = "index." + formats.extension(to_);
@@ -402,6 +404,29 @@ bool Converters::convert(Buffer const * buffer,
 						   "tmpfile.out"));
 		}
 
+		if (conv.need_auth()) {
+			static const char securityWarning[] = "LyX is about to run converter '%1$s' which is launching an external program that normally acts as a picture/format converter. However, this external program is known to be able to execute arbitrary actions on the system, including dangerous ones such as deleting files, if instructed to do so by a maliciously crafted .lyx document.\n Would you like to proceed?\nAnswer Yes only if you trust the source/sender of the .lyx document!";
+			int choice;
+			if (buffer) {
+				std::string const & fname = buffer->filePath();
+				if (auth_files.find(fname) == auth_files.end()) {
+					choice = frontend::Alert::prompt(
+						 _("Launch of external converter needs user authorization"), bformat(_(securityWarning), from_utf8(conv.command())),
+						0, 0, _("&No"), _("&Yes"), _("Yes, &and do not ask again for document"));
+					if (choice == 2)
+						auth_files.insert(fname);
+				} else {
+					choice = 1;
+				}
+			} else {
+				choice = frontend::Alert::prompt(
+					 _("Need user authorization to launch external converter"), bformat(_(securityWarning), from_utf8(conv.command())),
+					0, 0, _("&No"), _("&Yes"));
+			}
+			if (choice == 0)
+				return false;
+		}
+
 		if (conv.latex()) {
 			run_latex = true;
 			string command = conv.command();
diff --git a/src/Converter.h b/src/Converter.h
index c9c44238..9bde8714 100644
--- a/src/Converter.h
+++ b/src/Converter.h
@@ -70,6 +70,8 @@ public:
 	///
 	bool need_aux() const { return need_aux_; }
 	///
+	bool need_auth() const { return need_auth_; }
+	///
 	bool nice() const { return nice_; }
 	///
 	std::string const result_dir() const { return result_dir_; }
@@ -77,6 +79,7 @@ public:
 	std::string const result_file() const { return result_file_; }
 	///
 	std::string const parselog() const { return parselog_; }
+
 private:
 	///
 	trivstring from_;
@@ -101,6 +104,8 @@ private:
 	bool need_aux_;
 	/// we need a "nice" file from the backend, c.f. OutputParams.nice.
 	bool nice_;
+	/// Use of this converter needs explicit user authorization
+	bool need_auth_;
 	/// If the converter put the result in a directory, then result_dir
 	/// is the name of the directory
 	trivstring result_dir_;
@@ -181,6 +186,7 @@ public:
 	const_iterator end() const { return converterlist_.end(); }
 	///
 	void buildGraph();
+
 private:
 	///
 	FormatList const
@@ -210,6 +216,8 @@ private:
 		  bool copy);
 	///
 	Graph G_;
+	/// set of files authorized for external conversion
+	std::set<std::string> auth_files;
 };
 
 /// The global instance.
diff --git a/src/graphics/GraphicsConverter.cpp b/src/graphics/GraphicsConverter.cpp
index 67b1580f..6017073f 100644
--- a/src/graphics/GraphicsConverter.cpp
+++ b/src/graphics/GraphicsConverter.cpp
@@ -15,6 +15,7 @@
 #include "Converter.h"
 #include "Format.h"
 
+#include "frontends/alert.h"
 #include "support/lassert.h"
 #include "support/convert.h"
 #include "support/debug.h"
@@ -372,6 +373,15 @@ static void build_script(string const & from_file,
 			outfile = tempfile.name().toFilesystemEncoding();
 		}
 
+		if (conv.need_auth()) {
+			static const char securityWarning[] = "LyX is about to run converter '%1$s' which is launching an external program that normally acts as a picture/format converter. However, this external program is known to be able to execute arbitrary actions on the system, including dangerous ones such as deleting files, if instructed to do so by a maliciously crafted .lyx document.\n Would you like to proceed?\nAnswer Yes only if you trust the source/sender of the .lyx document!";
+			docstring const & question = bformat(from_utf8(securityWarning), from_utf8(conv.command()));
+			int choice = frontend::Alert::prompt(
+				from_utf8("Need user authorization to launch external converter"), question, 0, 0, from_utf8("&No"), from_utf8("&Yes"));
+			if (choice == 0)
+				return;
+		}
+
 		// Store these names in the python script
 		script << "infile = "
 				<< quoteName(infile, quote_python) << "\n"

Reply via email to