summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/sqlite3.rst14
-rw-r--r--Doc/whatsnew/3.10.rst8
-rw-r--r--Lib/test/audit-tests.py21
-rw-r--r--Lib/test/test_audit.py23
-rw-r--r--Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst3
-rw-r--r--Modules/_sqlite/connection.c9
-rw-r--r--Modules/_sqlite/module.c8
7 files changed, 86 insertions, 0 deletions
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
index 6bdf4ed..d0f28db 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 <https://www.sqlite.org/uri.html>`_.
.. 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)
@@ -467,8 +471,13 @@ Connection Objects
Loadable extensions are disabled by default. See [#f1]_.
+ .. audit-event:: sqlite3.enable_load_extension connection,enabled sqlite3.enable_load_extension
+
.. versionadded:: 3.2
+ .. versionchanged:: 3.10
+ Added the ``sqlite3.enable_load_extension`` auditing event.
+
.. literalinclude:: ../includes/sqlite3/load_extension.py
.. method:: load_extension(path)
@@ -479,8 +488,13 @@ Connection Objects
Loadable extensions are disabled by default. See [#f1]_.
+ .. audit-event:: sqlite3.load_extension connection,path sqlite3.load_extension
+
.. versionadded:: 3.2
+ .. versionchanged:: 3.10
+ Added the ``sqlite3.load_extension`` auditing event.
+
.. attribute:: row_factory
You can change this attribute to a callable that accepts the cursor and the
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 1d9c03c..91ad8ec 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -1080,6 +1080,14 @@ 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 :func:`~sqlite3.connect/handle`,
+:meth:`~sqlite3.Connection.enable_load_extension`, and
+:meth:`~sqlite3.Connection.load_extension`.
+(Contributed by Erlend E. Aasland in :issue:`43762`.)
+
sys
---
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index 2addf97..ed42451 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -359,6 +359,27 @@ def test_http_client():
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 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__":
from test.support import suppress_msvcrt_asserts
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index 456a5da..4ba62c4 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -130,6 +130,7 @@ class AuditTest(unittest.TestCase):
["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,27 @@ class AuditTest(unittest.TestCase):
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", "sqlite3.connect/handle"]
+
+ if hasattr(sqlite3.Connection, "enable_load_extension"):
+ expected += [
+ "sqlite3.enable_load_extension",
+ "sqlite3.load_extension",
+ ]
+ self.assertEqual(actual, expected)
+
+
if __name__ == "__main__":
unittest.main()
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 0000000..aa39265
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2021-04-07-12-57-41.bpo-43762.7lMtpT.rst
@@ -0,0 +1,3 @@
+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 150291c..5f8e41b 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -1154,6 +1154,11 @@ pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self,
{
int rc;
+ if (PySys_Audit("sqlite3.enable_load_extension",
+ "OO", self, onoff ? Py_True : Py_False) < 0) {
+ return NULL;
+ }
+
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
}
@@ -1185,6 +1190,10 @@ pysqlite_connection_load_extension_impl(pysqlite_Connection *self,
int rc;
char* errmsg;
+ if (PySys_Audit("sqlite3.load_extension", "Os", self, extension_name) < 0) {
+ return NULL;
+ }
+
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
}
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index 8dbfa7b..2f323fc 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;
}