From 4c66686f53e86dc0b86148a310db0bfc60c92253 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Tue, 8 Nov 2011 22:41:07 +0100
Subject: [PATCH] execute commands without use_shell=True to prevent remote
 code execution, except for commands configured in triggers plugin (configured
 by user itself). Fixes #7031

---
 src/common/helpers.py | 15 +++++++++++++--
 src/notify.py         |  2 +-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/common/helpers.py b/src/common/helpers.py
index 722fbebe24..97996f01ba 100644
--- a/src/common/helpers.py
+++ b/src/common/helpers.py
@@ -40,6 +40,7 @@ import errno
 import select
 import base64
 import hashlib
+import shlex
 import caps_cache
 
 from encodings.punycode import punycode_encode
@@ -381,8 +382,18 @@ def is_in_path(command, return_abs_path=False):
             pass
     return False
 
-def exec_command(command):
-    subprocess.Popen('%s &' % command, shell=True).wait()
+def exec_command(command, use_shell=False):
+    """
+    execute a command. if use_shell is True, we run the command as is it was
+    typed in a console. So it may be dangerous if you are not sure about what
+    is executed.
+    """
+    if use_shell:
+        subprocess.Popen('%s &' % command, shell=True).wait()
+    else:
+        args = shlex.split(command.encode('utf-8'))
+        p = subprocess.Popen(args)
+        gajim.thread_interface(p.wait)
 
 def build_command(executable, parameter):
     # we add to the parameter (can hold path with spaces)
diff --git a/src/notify.py b/src/notify.py
index a8a7378634..1f6eada51c 100644
--- a/src/notify.py
+++ b/src/notify.py
@@ -167,7 +167,7 @@ class Notification:
 
         if obj.do_command:
             try:
-                helpers.exec_command(obj.command)
+                helpers.exec_command(obj.command, use_shell=True)
             except Exception:
                 pass
 
-- 
GitLab