CVE-2022-1531: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value: SQL injection vulnerability in ARAX-UI Synonym Lookup functionality in GitHub repository rtxteam/rtx prior to checkpoint_2022-04-20 . This vulnerability is critical as it can lead to remote code execution and thus complete server takeover.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
CVSS v3 base score: 9.8
Published: 2022-04-29T09:15Z
Repository: https://github.com/rtxteam/rtx
Language: Python
Files changed: code/autocomplete/rtxcomplete.py
Commit date: 2022-04-20 18:38:35 +0000
Commit message: avoid SQL injection exploits

Diff: diff --git a/code/autocomplete/rtxcomplete.py b/code/autocomplete/rtxcomplete.py
index 71439853..4ad23484 100644
--- a/code/autocomplete/rtxcomplete.py
+++ b/code/autocomplete/rtxcomplete.py
@@ -21,10 +21,11 @@ def load():
     global conn
     global cursor
     database_name = f"{autocomplete_filepath}{os.path.sep}{RTXConfig.autocomplete_path.split('/')[-1]}"
     conn = sqlite3.connect(database_name)
     cursor = conn.cursor()
+    #print(f"INFO: Connected to {database_name}",file=sys.stderr)
     return True
 
 
 def get_nodes_like(word,requested_limit):
 
@@ -37,10 +38,13 @@ def get_nodes_like(word,requested_limit):
     n_values = 0
 
     if len(word) < 2:
         return values
 
+    #### Try to avoid SQL injection exploits by sanitizing input #1823
+    word = word.replace('"','')
+
     floor = word[:-1]
     ceiling = floor + 'zz'
 
     #### Get a list of matching node names that begin with these letters
     if debug:
@@ -101,12 +105,16 @@ def get_nodes_like(word,requested_limit):
 
 
         if found_fragment is None:
 
             #### Cache this fragment in the database
-            cursor.execute("INSERT INTO cached_fragments(fragment) VALUES(?)", (word,))
-            fragment_id = cursor.lastrowid
+            try:
+                cursor.execute("INSERT INTO cached_fragments(fragment) VALUES(?)", (word,))
+                fragment_id = cursor.lastrowid
+            except:
+                print(f"ERROR: Unable to INSERT into cached_fragments(fragment)",file=sys.stderr)
+                fragment_id = 0
             if debug:
                 print(f"fragment_id = {fragment_id}")
 
             #### Execute an expensive LIKE query
             cursor.execute("SELECT term FROM terms WHERE term LIKE \"%%%s%%\" ORDER BY length(term),term LIMIT %s" % (word,10000))

Vulnerable code:             cursor.execute("INSERT INTO cached_fragments(fragment) VALUES(?)", (word,))
            fragment_id = cursor.lastrowid
Fixed code:     #print(f"INFO: Connected to {database_name}",file=sys.stderr)
    #### Try to avoid SQL injection exploits by sanitizing input #1823
    word = word.replace('"','')

            try:
                cursor.execute("INSERT INTO cached_fragments(fragment) VALUES(?)", (word,))
                fragment_id = cursor.lastrowid
            except:
                print(f"ERROR: Unable to INSERT into cached_fragments(fragment)",file=sys.stderr)
                fragment_id = 0