]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0561: [security]: possible code execution with python3complete v9.2.0561
authorChristian Brabandt <cb@256bit.org>
Fri, 29 May 2026 19:05:53 +0000 (19:05 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 29 May 2026 19:08:20 +0000 (19:08 +0000)
Problem:  [security]: possible code execution with python3complete
Solution: Disable execution of import/from statements

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-52mc-rq6p-rc7c

Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/autoload/README.txt
runtime/autoload/python3complete.vim
runtime/autoload/pythoncomplete.vim
runtime/doc/filetype.txt
src/version.c

index 3b18d3dde5a281d8eb9d64538090a570eae0c157..b22581963ec3cf4f5f3aa5778ab4a0b1bb840a30 100644 (file)
@@ -17,6 +17,7 @@ htmlcomplete.vim      HTML
 javascriptcomplete.vim  Javascript
 phpcomplete.vim                PHP
 pythoncomplete.vim     Python
+python3complete.vim Python
 rubycomplete.vim       Ruby
 syntaxcomplete.vim     from syntax highlighting
 xmlcomplete.vim                XML (uses files in the xml directory)
index 3e54433f41ff15c1669400fcaaede944ada2c2da..2b6a6525256ba4e7702fc1edfbf41d1b9863a7a9 100644 (file)
 "   i.e. "import url<c-x,c-o>"
 " Continue parsing on invalid line??
 "
+" v 0.10 by Vim project
+"   * disables importing local modules, unless the global Vim variable
+"     g:pythoncomplete_allow_import is set to non-zero
+"
 " v 0.9
 "   * Fixed docstring parsing for classes and functions
 "   * Fixed parsing of *args and **kwargs type arguments
@@ -132,11 +136,20 @@ class Completer(object):
 
     def evalsource(self,text,line=0):
         sc = self.parser.parse(text,line)
+        try: allow_imports = int(
+          vim.eval("get(g:, 'pythoncomplete_allow_import', 0)"))
+        except Exception:
+          allow_imports = 0
         src = sc.get_code()
         dbg("source: %s" % src)
         try: exec(src,self.compldict)
         except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1]))
         for l in sc.locals:
+            # Executing import/from statements harvested from the buffer runs
+            # arbitrary package code; only do so when the user opted in.
+            if not allow_imports and (l.startswith('import')
+                                            or l.startswith('from ')):
+                continue
             try: exec(l,self.compldict)
             except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l))
 
@@ -300,13 +313,11 @@ class Scope(object):
     def get_code(self):
         str = ""
         if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
-        for l in self.locals:
-            if l.startswith('import'): str += l+'\n'
         str += 'class _PyCmplNoType:\n    def __getattr__(self,name):\n        return None\n'
         for sub in self.subscopes:
             str += sub.get_code()
         for l in self.locals:
-            if not l.startswith('import'): str += l+'\n'
+            if not l.startswith('import') and not l.startswith('from '): str += l+'\n'
 
         return str
 
index aa28bb721fa865b321f3b673c1f729f875a9771d..10147767ef96747bb2aeeca2ff354ce8d91130e2 100644 (file)
 "   i.e. "import url<c-x,c-o>"
 " Continue parsing on invalid line??
 "
+" v 0.10 by Vim project
+"   * disables importing local modules, unless the global Vim variable
+"     g:pythoncomplete_allow_import is set to non-zero
+"
 " v 0.9
 "   * Fixed docstring parsing for classes and functions
 "   * Fixed parsing of *args and **kwargs type arguments
@@ -146,11 +150,20 @@ class Completer(object):
 
     def evalsource(self,text,line=0):
         sc = self.parser.parse(text,line)
+        try: allow_imports = int(
+          vim.eval("get(g:, 'pythoncomplete_allow_import', 0)"))
+        except Exception:
+          allow_imports = 0
         src = sc.get_code()
         dbg("source: %s" % src)
         try: exec(src) in self.compldict
         except: dbg("parser: %s, %s" % (sys.exc_info()[0],sys.exc_info()[1]))
         for l in sc.locals:
+            # Executing import/from statements harvested from the buffer runs
+            # arbitrary package code; only do so when the user opted in.
+            if not allow_imports and (l.startswith('import')
+                                            or l.startswith('from ')):
+                continue
             try: exec(l) in self.compldict
             except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l))
 
@@ -315,13 +328,11 @@ class Scope(object):
     def get_code(self):
         str = ""
         if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
-        for l in self.locals:
-            if l.startswith('import'): str += l+'\n'
         str += 'class _PyCmplNoType:\n    def __getattr__(self,name):\n        return None\n'
         for sub in self.subscopes:
             str += sub.get_code()
         for l in self.locals:
-            if not l.startswith('import'): str += l+'\n'
+            if not l.startswith('import') and not l.startswith('from '): str += l+'\n'
 
         return str
 
index 80c3bb810f9cb5c527e374e4661df0f176874396..a9a0e922034473261e78340a30ee548cf759ac2f 100644 (file)
@@ -976,7 +976,20 @@ By default the following options are set, in accordance with PEP8: >
 To disable this behavior, set the following variable in your vimrc: >
 
        let g:python_recommended_style = 0
-
+<
+Python omni-completion |compl-omni| is provided by python3complete.vim (or
+pythoncomplete.vim) for Vim builds with the |+python|/|+python3| interpreter.
+By default it does not inspect the import / from statements found in the
+buffer. This means completion of names defined in the buffer itself (classes,
+functions, variables) works, but completion of members of imported modules is
+not offered.
+
+To enable completion of imported module members, set: >
+       let g:pythoncomplete_allow_import = 1
+<
+WARNING: enabling this causes omni-completion to execute the import statements
+found in the buffer through Python's import machinery, which runs the imported
+modules' top-level code. Only enable this for code you trust.
 
 QF QUICKFIX                                        *qf.vim* *ft-qf-plugin*
 
index cb845499e4726d1ff7f3a86a604bda1c369f5190..d7e0f590fca7f7ee155ff468c2b6602ad5c13d9c 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    561,
 /**/
     560,
 /**/