CVE-2021-3119 (published 2021-03-25T23:15Z)

Zetetic SQLCipher 4.x before 4.4.3 has a NULL pointer dereferencing issue related to sqlcipher_export in crypto.c and sqlite3StrICmp in sqlite3.c. This may allow an attacker to perform a remote denial of service attack. For example, an SQL injection can be used to execute the crafted SQL command sequence, which causes a segmentation fault.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/sqlcipher/sqlcipher
commit_details: repo_url: https://github.com/sqlcipher/sqlcipher
author: Stephen Lombardo
author_date: 2021-01-13 17:24:33-05:00
msg: fix sqlcipher_export handling of NULL parameters
repository: repo_url: https://github.com/sqlcipher/sqlcipher
repo_name: sqlcipher/sqlcipher
description: SQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files and other security features.
repo_language: C
owner: sqlcipher
file_changes: filename: crypto.c
change_type: ModificationType.MODIFY
diff: @@ -1075,13 +1075,29 @@ void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **ar
     goto end_of_export;
   }
 
-  targetDb = (const char*) sqlite3_value_text(argv[0]);
-  sourceDb = (argc == 2) ? (char *) sqlite3_value_text(argv[1]) : "main";
+  if(sqlite3_value_type(argv[0]) == SQLITE_NULL) {
+    rc = SQLITE_ERROR;
+    pzErrMsg = sqlite3_mprintf("target database can't be NULL");
+    goto end_of_export;
+  }
+
+  targetDb = (const char*) sqlite3_value_text(argv[0]); 
+  sourceDb = "main";
+
+  if(argc == 2) {
+    if(sqlite3_value_type(argv[1]) == SQLITE_NULL) {
+      rc = SQLITE_ERROR;
+      pzErrMsg = sqlite3_mprintf("target database can't be NULL");
+      goto end_of_export;
+    }
+    sourceDb = (char *) sqlite3_value_text(argv[1]);
+  }
+
 
   /* if the name of the target is not main, but the index returned is zero 
      there is a mismatch and we should not proceed */
   targetDb_idx =  sqlcipher_find_db_index(db, targetDb);
-  if(targetDb_idx == 0 && sqlite3StrICmp("main", targetDb) != 0) {
+  if(targetDb_idx == 0 && targetDb != NULL && sqlite3StrICmp("main", targetDb) != 0) {
     rc = SQLITE_ERROR;
     pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb);
     goto end_of_export;

programming_language: C
filename: sqlcipher-compatibility.test
change_type: ModificationType.MODIFY
diff: @@ -444,6 +444,32 @@ do_test export-error {
 db close
 file delete -force test.db
 
+# verify sqlcipher_export with NULL parameters
+do_test export-nulls {
+  sqlite_orig db test.db
+
+  catchsql {
+    SELECT sqlcipher_export(NULL);
+  }
+
+} {1 {target database can't be NULL}}
+db close
+file delete -force test.db
+
+do_test export-nulls {
+  sqlite_orig db test.db
+
+  catchsql {
+    SELECT sqlcipher_export('main', NULL);
+  }
+
+} {1 {target database can't be NULL}}
+db close
+file delete -force test.db
+
+
+# use the sqlcipher_export function
+
 # use the sqlcipher_export function
 # to copy a complicated database. 
 # tests autoincrement fields,

programming_language: SQL