[Pkg-javascript-devel] Bug#1032976: unblock: node-sqlite3/5.1.5+ds1-1

Yadd yadd at debian.org
Wed Mar 15 02:33:08 GMT 2023


Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock
X-Debbugs-Cc: node-sqlite3 at packages.debian.org
Control: affects -1 + src:node-sqlite3

Please unblock package node-sqlite3

[ Reason ]
A code execution vulnerability was discover in node-sqlite3 due to the
underlying implementation of .toString(). It is then possible to execute
arbitrary JavaScript or to achieve a denial-of-service. if a binding
parameter is a crafted object.
(CVE-2022-43441)

[ Impact ]
Major security issue

[ Tests ]
New test added, passed

[ Risks ]
No risk, patch is trivial. The main change is this:

    @@ -208,7 +208,7 @@ template <class T> Values::Field*
             return new Values::Float(pos, source.ToNumber().DoubleValue());
         }
         else if (source.IsObject()) {
    -        Napi::String napiVal = source.ToString();
    +        Napi::String napiVal = Napi::String::New(source.Env(), "[object Object]");
             // Check whether toString returned a value that is not undefined.
             if(napiVal.Type() == 0) {
                 return NULL;


[ Checklist ]
  [X] all changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in testing

[ Other info ]
DSA pushed also for bullseye (5.0.0+ds1-1+deb11u2)

unblock node-sqlite3/5.1.5+ds1-1
-------------- next part --------------
diff --git a/README.md b/README.md
index 4a214a6..571df9e 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Asynchronous, non-blocking [SQLite3](https://sqlite.org/) bindings for [Node.js]
  - [Extension support](https://github.com/TryGhost/node-sqlite3/wiki/API#databaseloadextensionpath-callback), including bundled support for the [json1 extension](https://www.sqlite.org/json1.html)
  - Big test suite
  - Written in modern C++ and tested for memory leaks
- - Bundles SQLite v3.39.4, or you can build using a local SQLite
+ - Bundles SQLite v3.41.1, or you can build using a local SQLite
 
 # Installing
 
diff --git a/binding.gyp b/binding.gyp
index f1336f6..20d418b 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -25,8 +25,10 @@
             "libraries": [
                "-l<(sqlite_libname)"
             ],
-            "conditions": [ [ "OS=='linux'", {"libraries+":["-Wl,-rpath=<@(sqlite)/lib"]} ] ],
-            "conditions": [ [ "OS!='win'", {"libraries+":["-L<@(sqlite)/lib"]} ] ],
+            "conditions": [
+              [ "OS=='linux'", {"libraries+":["-Wl,-rpath=<@(sqlite)/lib"]} ],
+              [ "OS!='win'", {"libraries+":["-L<@(sqlite)/lib"]} ]
+            ],
             'msvs_settings': {
               'VCLinkerTool': {
                 'AdditionalLibraryDirectories': [
diff --git a/debian/changelog b/debian/changelog
index a1b24b6..5eb4c18 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+node-sqlite3 (5.1.5+ds1-1) unstable; urgency=medium
+
+  * Team upload
+  * Update lintian override info format in d/source/lintian-overrides
+    on line 2-3
+  * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository-Browse
+  * Update standards version to 4.6.2, no changes needed.
+  * New upstream version (Closes: CVE-2022-43441)
+
+ -- Yadd <yadd at debian.org>  Tue, 14 Mar 2023 07:04:46 +0400
+
 node-sqlite3 (5.1.2+ds1-1) unstable; urgency=medium
 
   * Team upload
diff --git a/debian/control b/debian/control
index e775fb8..cd29f0e 100644
--- a/debian/control
+++ b/debian/control
@@ -16,7 +16,7 @@ Build-Depends:
  , mocha
  , libsqlite3-dev
  , dh-sequence-nodejs
-Standards-Version: 4.6.1
+Standards-Version: 4.6.2
 Homepage: https://github.com/mapbox/node-sqlite3/wiki
 Vcs-Git: https://salsa.debian.org/js-team/node-sqlite3.git
 Vcs-Browser: https://salsa.debian.org/js-team/node-sqlite3
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
index 6694acf..30e1e92 100644
--- a/debian/source/lintian-overrides
+++ b/debian/source/lintian-overrides
@@ -1,5 +1,5 @@
 # only long lines, source is readable
-source-is-missing *test/null_error.test.js*
-source-contains-prebuilt-javascript-object *test/null_error.test.js*
+source-is-missing [*test/null_error.test.js*]
+source-contains-prebuilt-javascript-object [*test/null_error.test.js*]
 very-long-line-length-in-source-file *.md*
 very-long-line-length-in-source-file *test/null_error.test.js*
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
index 4b6a0f1..b794be2 100644
--- a/debian/upstream/metadata
+++ b/debian/upstream/metadata
@@ -1,6 +1,6 @@
 ---
 Archive: GitHub
-Bug-Database: https://github.com/mapbox/node-sqlite3/issues
-Bug-Submit: https://github.com/mapbox/node-sqlite3/issues/new
+Bug-Database: https://github.com/TryGhost/node-sqlite3/issues
+Bug-Submit: https://github.com/TryGhost/node-sqlite3/issues/new
 Repository: https://github.com/mapbox/node-sqlite3.git
-Repository-Browse: https://github.com/mapbox/node-sqlite3
+Repository-Browse: https://github.com/TryGhost/node-sqlite3
diff --git a/deps/common-sqlite.gypi b/deps/common-sqlite.gypi
index 4be536c..9d70d3b 100644
--- a/deps/common-sqlite.gypi
+++ b/deps/common-sqlite.gypi
@@ -1,6 +1,6 @@
 {
   'variables': {
-      'sqlite_version%':'3390400',
+      'sqlite_version%':'3410100',
       "toolset%":'',
   },
   'target_defaults': {
diff --git a/package.json b/package.json
index 530294f..6193ae8 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "sqlite3",
   "description": "Asynchronous, non-blocking SQLite3 bindings",
-  "version": "5.1.2",
+  "version": "5.1.5",
   "homepage": "https://github.com/TryGhost/node-sqlite3",
   "author": {
     "name": "Mapbox",
diff --git a/src/database.cc b/src/database.cc
index b16b1f7..15709ce 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -56,7 +56,7 @@ void Database::Process() {
             queue.pop();
             std::unique_ptr<Baton> baton(call->baton);
             Napi::Function cb = baton->callback.Value();
-            if (!cb.IsUndefined() && cb.IsFunction()) {
+            if (IS_FUNCTION(cb)) {
                 TRY_CATCH_CALL(this->Value(), cb, 1, argv);
                 called = true;
             }
@@ -97,7 +97,7 @@ void Database::Schedule(Work_Callback callback, Baton* baton, bool exclusive) {
         // We don't call the actual callback, so we have to make sure that
         // the baton gets destroyed.
         delete baton;
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             Napi::Value argv[] = { exception };
             TRY_CATCH_CALL(Value(), cb, 1, argv);
         }
@@ -202,7 +202,7 @@ void Database::Work_AfterOpen(napi_env e, napi_status status, void* data) {
 
     Napi::Function cb = baton->callback.Value();
 
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         TRY_CATCH_CALL(db->Value(), cb, 1, argv);
     }
     else if (!db->open) {
@@ -294,7 +294,7 @@ void Database::Work_AfterClose(napi_env e, napi_status status, void* data) {
     Napi::Function cb = baton->callback.Value();
 
     // Fire callbacks.
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         TRY_CATCH_CALL(db->Value(), cb, 1, argv);
     }
     else if (db->open) {
@@ -630,7 +630,7 @@ void Database::Work_AfterExec(napi_env e, napi_status status, void* data) {
     if (baton->status != SQLITE_OK) {
         EXCEPTION(Napi::String::New(env, baton->message.c_str()), baton->status, exception);
 
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             Napi::Value argv[] = { exception };
             TRY_CATCH_CALL(db->Value(), cb, 1, argv);
         }
@@ -639,7 +639,7 @@ void Database::Work_AfterExec(napi_env e, napi_status status, void* data) {
             EMIT_EVENT(db->Value(), 2, info);
         }
     }
-    else if (!cb.IsUndefined() && cb.IsFunction()) {
+    else if (IS_FUNCTION(cb)) {
         Napi::Value argv[] = { env.Null() };
         TRY_CATCH_CALL(db->Value(), cb, 1, argv);
     }
@@ -671,7 +671,7 @@ void Database::Work_Wait(Baton* b) {
     assert(baton->db->pending == 0);
 
     Napi::Function cb = baton->callback.Value();
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         Napi::Value argv[] = { env.Null() };
         TRY_CATCH_CALL(baton->db->Value(), cb, 1, argv);
     }
@@ -742,7 +742,7 @@ void Database::Work_AfterLoadExtension(napi_env e, napi_status status, void* dat
     if (baton->status != SQLITE_OK) {
         EXCEPTION(Napi::String::New(env, baton->message.c_str()), baton->status, exception);
 
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             Napi::Value argv[] = { exception };
             TRY_CATCH_CALL(db->Value(), cb, 1, argv);
         }
@@ -751,7 +751,7 @@ void Database::Work_AfterLoadExtension(napi_env e, napi_status status, void* dat
             EMIT_EVENT(db->Value(), 2, info);
         }
     }
-    else if (!cb.IsUndefined() && cb.IsFunction()) {
+    else if (IS_FUNCTION(cb)) {
         Napi::Value argv[] = { env.Null() };
         TRY_CATCH_CALL(db->Value(), cb, 1, argv);
     }
diff --git a/src/macros.h b/src/macros.h
index b46a875..344642d 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -23,6 +23,9 @@ inline bool OtherIsInt(Napi::Number source) {
     }
 }
 
+#define IS_FUNCTION(cb) \
+    !cb.IsUndefined() && cb.IsFunction()
+
 #define REQUIRE_ARGUMENTS(n)                                                   \
     if (info.Length() < (n)) {                                                 \
         Napi::TypeError::New(env, "Expected " #n "arguments").ThrowAsJavaScriptException(); \
diff --git a/src/statement.cc b/src/statement.cc
index 6adb123..29e06f9 100644
--- a/src/statement.cc
+++ b/src/statement.cc
@@ -77,7 +77,7 @@ template <class T> void Statement::Error(T* baton) {
 
     Napi::Function cb = baton->callback.Value();
 
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         Napi::Value argv[] = { exception };
         TRY_CATCH_CALL(stmt->Value(), cb, 1, argv);
     }
@@ -208,7 +208,7 @@ template <class T> Values::Field*
         return new Values::Float(pos, source.ToNumber().DoubleValue());
     }
     else if (source.IsObject()) {
-        Napi::String napiVal = source.ToString();
+        Napi::String napiVal = Napi::String::New(source.Env(), "[object Object]");
         // Check whether toString returned a value that is not undefined.
         if(napiVal.Type() == 0) {
             return NULL;
@@ -375,7 +375,7 @@ void Statement::Work_AfterBind(napi_env e, napi_status status, void* data) {
     else {
         // Fire callbacks.
         Napi::Function cb = baton->callback.Value();
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             Napi::Value argv[] = { env.Null() };
             TRY_CATCH_CALL(stmt->Value(), cb, 1, argv);
         }
@@ -442,7 +442,7 @@ void Statement::Work_AfterGet(napi_env e, napi_status status, void* data) {
     else {
         // Fire callbacks.
         Napi::Function cb = baton->callback.Value();
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             if (stmt->status == SQLITE_ROW) {
                 // Create the result array from the data we acquired.
                 Napi::Value argv[] = { env.Null(), RowToJS(env, &baton->row) };
@@ -516,7 +516,7 @@ void Statement::Work_AfterRun(napi_env e, napi_status status, void* data) {
     else {
         // Fire callbacks.
         Napi::Function cb = baton->callback.Value();
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             (stmt->Value()).Set(Napi::String::New(env, "lastID"), Napi::Number::New(env, baton->inserted_id));
             (stmt->Value()).Set( Napi::String::New(env, "changes"), Napi::Number::New(env, baton->changes));
 
@@ -586,7 +586,7 @@ void Statement::Work_AfterAll(napi_env e, napi_status status, void* data) {
     else {
         // Fire callbacks.
         Napi::Function cb = baton->callback.Value();
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             if (baton->rows.size()) {
                 // Create the result array from the data we acquired.
                 Napi::Array result(Napi::Array::New(env, baton->rows.size()));
@@ -716,7 +716,7 @@ void Statement::AsyncEach(uv_async_t* handle) {
         }
 
         Napi::Function cb = async->item_cb.Value();
-        if (!cb.IsUndefined() && cb.IsFunction()) {
+        if (IS_FUNCTION(cb)) {
             Napi::Value argv[2];
             argv[0] = env.Null();
 
@@ -791,7 +791,7 @@ void Statement::Work_AfterReset(napi_env e, napi_status status, void* data) {
 
     // Fire callbacks.
     Napi::Function cb = baton->callback.Value();
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         Napi::Value argv[] = { env.Null() };
         TRY_CATCH_CALL(stmt->Value(), cb, 1, argv);
     }
@@ -893,7 +893,7 @@ void Statement::Finalize_(Baton* b) {
 
     // Fire callback in case there was one.
     Napi::Function cb = baton->callback.Value();
-    if (!cb.IsUndefined() && cb.IsFunction()) {
+    if (IS_FUNCTION(cb)) {
         TRY_CATCH_CALL(baton->stmt->Value(), cb, 0, NULL);
     }
 }
diff --git a/test/other_objects.test.js b/test/other_objects.test.js
index 7185987..cc516c4 100644
--- a/test/other_objects.test.js
+++ b/test/other_objects.test.js
@@ -95,4 +95,20 @@ describe('data types', function() {
         });
     });
 
+    it('should ignore faulty toString in array', function(done) {
+        const faulty = [[{toString: null}], 1];
+        db.all('SELECT * FROM txt_table WHERE txt = ? LIMIT ?', faulty, function (err) {
+            assert.equal(err, null);
+            done();
+        });
+    });
+
+    it('should ignore faulty toString set to function', function(done) {
+        const faulty = [[{toString: function () {console.log('oh no');}}], 1];
+        db.all('SELECT * FROM txt_table WHERE txt = ? LIMIT ?', faulty, function (err) {
+            assert.equal(err, undefined);
+            done();
+        });
+    });
+
 });


More information about the Pkg-javascript-devel mailing list