From 61cb9e58fca89e3b4deaeaf64dd6a6a9404207cc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 7 Apr 2021 12:29:38 +0200 Subject: [PATCH 01/11] Add sqlite3.enable_load_extension audit event --- Modules/_sqlite/connection.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 150291cb72396d0..4712ca3b4aee353 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1154,6 +1154,10 @@ pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, { int rc; + if (PySys_Audit("sqlite3.enable_load_extension", "i", onoff) < 0) { + return NULL; + } + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } From 7bc5c179e679da8621a5a18b92ca65fd570f228c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 7 Apr 2021 12:52:28 +0200 Subject: [PATCH 02/11] Add sqlite3.load_extension audit event --- Modules/_sqlite/connection.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 4712ca3b4aee353..bdd5b5bd3c8be45 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1189,6 +1189,10 @@ pysqlite_connection_load_extension_impl(pysqlite_Connection *self, int rc; char* errmsg; + if (PySys_Audit("sqlite3.load_extension", "s", extension_name) < 0) { + return NULL; + } + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } From 38ed2efba35243df4110f0da9cb9cbbb26631e90 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 7 Apr 2021 13:01:20 +0200 Subject: [PATCH 03/11] Add NEWS --- .../next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst diff --git a/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst b/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst new file mode 100644 index 000000000000000..84aaf43fb66dbc6 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst @@ -0,0 +1,2 @@ +Add audit events for :meth:`sqlite3.Connection.enable_load_extension` and +:meth:`sqlite3.Connection.load_extension`. Patch by Erlend E. Aasland. From ffedcfc72e67181b346c4f5d9c61858af7f9870b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 7 Apr 2021 13:01:38 +0200 Subject: [PATCH 04/11] Update "What's New" --- Doc/whatsnew/3.10.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 78f3c2d36b845c1..fc545f0540339f7 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1068,6 +1068,13 @@ ssl Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function. (Contributed by Zackery Spytz in :issue:`31870`.) +sqlite3 +------- + +Add audit events for :meth:`~sqlite3.Connection.enable_load_extension` and +:meth:`~sqlite3.Connection.load_extension`. +(Contributed by Erlend E. Aasland in :issue:`43762`.) + sys --- From 102986023daa04ebc2199dbaf690ecf9020935ce Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 7 Apr 2021 13:27:17 +0200 Subject: [PATCH 05/11] Add tests --- Lib/test/audit-tests.py | 23 +++++++++++++++++++++++ Lib/test/test_audit.py | 22 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 2addf9762eae497..1081147e97b58c8 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -359,6 +359,29 @@ def hook(event, args): conn.close() +def test_sqlite3(): + import sqlite3 + + def hook(event, *args): + if event.startswith("sqlite3."): + print(event, *args) + + sys.addaudithook(hook) + cx = sqlite3.connect(":memory:") + + # Configured without --enable-loadable-sqlite-extensions + if not hasattr(sqlite3.Connection, "enable_load_extension"): + return + + cx.enable_load_extension(False) + try: + cx.load_extension("test") + except sqlite3.OperationalError: + pass + else: + raise RuntimeError("Expected sqlite3.load_extension to fail") + + if __name__ == "__main__": from test.support import suppress_msvcrt_asserts diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 456a5daceb9f10a..d19068b76e38dc2 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -130,6 +130,7 @@ def test_gc(self): ["gc.get_objects", "gc.get_referrers", "gc.get_referents"] ) + def test_http(self): import_helper.import_module("http.client") returncode, events, stderr = self.run_python("test_http_client") @@ -145,5 +146,26 @@ def test_http(self): self.assertIn('HTTP', events[1][2]) + def test_sqlite3(self): + try: + import sqlite3 + except ImportError: + return + returncode, events, stderr = self.run_python("test_sqlite3") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [ev[0] for ev in events] + expected = ["sqlite3.connect"] + if hasattr(sqlite3.Connection, "enable_load_extension"): + expected += [ + "sqlite3.enable_load_extension", + "sqlite3.load_extension", + ] + self.assertEqual(actual, expected) + + if __name__ == "__main__": unittest.main() From 62e2d6b78c2419912a0690af2fbde57fde42777c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 22 Apr 2021 09:14:19 +0200 Subject: [PATCH 06/11] Update docs --- Doc/library/sqlite3.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 6bdf4ed0d81bcc7..0c655d3e61eddbf 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -467,8 +467,13 @@ Connection Objects Loadable extensions are disabled by default. See [#f1]_. + .. audit-event:: sqlite3.enable_load_extension enabled sqlite3.enable_load_extension + .. versionadded:: 3.2 + .. versionchanged:: 3.10 + Added auditing event. + .. literalinclude:: ../includes/sqlite3/load_extension.py .. method:: load_extension(path) @@ -479,8 +484,13 @@ Connection Objects Loadable extensions are disabled by default. See [#f1]_. + .. audit-event:: sqlite3.load_extension path sqlite3.load_extension + .. versionadded:: 3.2 + .. versionchanged:: 3.10 + Added auditing event. + .. attribute:: row_factory You can change this attribute to a callable that accepts the cursor and the From dd2ffdebf8872e23e364b35f23587c18dfd3672c Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Sun, 25 Apr 2021 00:39:55 +0200 Subject: [PATCH 07/11] Address review Co-authored-by: Steve Dower --- Lib/test/audit-tests.py | 18 ++++++++---------- Modules/_sqlite/connection.c | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 1081147e97b58c8..ed42451b8f08af2 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -370,16 +370,14 @@ def hook(event, *args): cx = sqlite3.connect(":memory:") # Configured without --enable-loadable-sqlite-extensions - if not hasattr(sqlite3.Connection, "enable_load_extension"): - return - - cx.enable_load_extension(False) - try: - cx.load_extension("test") - except sqlite3.OperationalError: - pass - else: - raise RuntimeError("Expected sqlite3.load_extension to fail") + if hasattr(sqlite3.Connection, "enable_load_extension"): + cx.enable_load_extension(False) + try: + cx.load_extension("test") + except sqlite3.OperationalError: + pass + else: + raise RuntimeError("Expected sqlite3.load_extension to fail") if __name__ == "__main__": diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index bdd5b5bd3c8be45..04ec47ae1714807 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1154,7 +1154,7 @@ pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, { int rc; - if (PySys_Audit("sqlite3.enable_load_extension", "i", onoff) < 0) { + if (PySys_Audit("sqlite3.enable_load_extension", "O", onoff ? Py_True : Py_False) < 0) { return NULL; } From c95870fc55d251a0d9596ecc659dacc14353bc51 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 26 Apr 2021 21:51:56 +0200 Subject: [PATCH 08/11] Add event for 'sqlite3.connect/handle', and pass connection object for post connect events --- Doc/whatsnew/3.10.rst | 3 ++- Lib/test/test_audit.py | 3 ++- .../Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst | 3 ++- Modules/_sqlite/connection.c | 5 +++-- Modules/_sqlite/module.c | 8 ++++++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index fc545f0540339f7..1e4666334d28e2c 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1071,7 +1071,8 @@ Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function. sqlite3 ------- -Add audit events for :meth:`~sqlite3.Connection.enable_load_extension` and +Add audit events for :func:`~sqlite3.connect/handle`, +:meth:`~sqlite3.Connection.enable_load_extension`, and :meth:`~sqlite3.Connection.load_extension`. (Contributed by Erlend E. Aasland in :issue:`43762`.) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index d19068b76e38dc2..4ba62c408526d35 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -158,7 +158,8 @@ def test_sqlite3(self): if support.verbose: print(*events, sep='\n') actual = [ev[0] for ev in events] - expected = ["sqlite3.connect"] + expected = ["sqlite3.connect", "sqlite3.connect/handle"] + if hasattr(sqlite3.Connection, "enable_load_extension"): expected += [ "sqlite3.enable_load_extension", diff --git a/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst b/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst index 84aaf43fb66dbc6..aa392656807e11f 100644 --- a/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst +++ b/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst @@ -1,2 +1,3 @@ -Add audit events for :meth:`sqlite3.Connection.enable_load_extension` and +Add audit events for :func:`sqlite3.connect/handle`, +:meth:`sqlite3.Connection.enable_load_extension`, and :meth:`sqlite3.Connection.load_extension`. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 04ec47ae1714807..5f8e41b6169a765 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1154,7 +1154,8 @@ pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, { int rc; - if (PySys_Audit("sqlite3.enable_load_extension", "O", onoff ? Py_True : Py_False) < 0) { + if (PySys_Audit("sqlite3.enable_load_extension", + "OO", self, onoff ? Py_True : Py_False) < 0) { return NULL; } @@ -1189,7 +1190,7 @@ pysqlite_connection_load_extension_impl(pysqlite_Connection *self, int rc; char* errmsg; - if (PySys_Audit("sqlite3.load_extension", "s", extension_name) < 0) { + if (PySys_Audit("sqlite3.load_extension", "Os", self, extension_name) < 0) { return NULL; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 8dbfa7b38a1f9c4..2f323fcd00141ff 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -96,6 +96,14 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* } result = PyObject_Call(factory, args, kwargs); + if (result == NULL) { + return NULL; + } + + if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) { + Py_DECREF(result); + return NULL; + } return result; } From 24e9efda0a4601665b63f397bff17ce0cada9fb0 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 26 Apr 2021 21:54:17 +0200 Subject: [PATCH 09/11] Update docs --- Doc/library/sqlite3.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 0c655d3e61eddbf..7e0341d4217ac10 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -225,6 +225,7 @@ Module functions and constants be found in the `SQLite URI documentation `_. .. audit-event:: sqlite3.connect database sqlite3.connect + .. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect .. versionchanged:: 3.4 Added the *uri* parameter. @@ -232,6 +233,9 @@ Module functions and constants .. versionchanged:: 3.7 *database* can now also be a :term:`path-like object`, not only a string. + .. versionchanged:: 3.10 + Added the ``sqlite3.connect/handle`` auditing event. + .. function:: register_converter(typename, callable) @@ -472,7 +476,7 @@ Connection Objects .. versionadded:: 3.2 .. versionchanged:: 3.10 - Added auditing event. + Added the ``sqlite3.enable_load_extension`` auditing event. .. literalinclude:: ../includes/sqlite3/load_extension.py @@ -489,7 +493,7 @@ Connection Objects .. versionadded:: 3.2 .. versionchanged:: 3.10 - Added auditing event. + Added the ``sqlite3.load_extension`` auditing event. .. attribute:: row_factory From 513032b904814f1e09d6239a85b22cbf83ebfe0d Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 26 Apr 2021 22:02:47 +0200 Subject: [PATCH 10/11] Update Doc/library/sqlite3.rst Co-authored-by: Steve Dower --- Doc/library/sqlite3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7e0341d4217ac10..b5820109b53345b 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -471,7 +471,7 @@ Connection Objects Loadable extensions are disabled by default. See [#f1]_. - .. audit-event:: sqlite3.enable_load_extension enabled sqlite3.enable_load_extension + .. audit-event:: sqlite3.enable_load_extension connection,enabled sqlite3.enable_load_extension .. versionadded:: 3.2 From 7da5f9f1893e7d815210345d0b61e889daf0b2d4 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 26 Apr 2021 22:03:03 +0200 Subject: [PATCH 11/11] Update Doc/library/sqlite3.rst Co-authored-by: Steve Dower --- Doc/library/sqlite3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index b5820109b53345b..d0f28db12fda16e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -488,7 +488,7 @@ Connection Objects Loadable extensions are disabled by default. See [#f1]_. - .. audit-event:: sqlite3.load_extension path sqlite3.load_extension + .. audit-event:: sqlite3.load_extension connection,path sqlite3.load_extension .. versionadded:: 3.2