Skip to content

Commit 8f0c6bb

Browse files
committed
feat: Lock down duckdb to limit filesystem access
1 parent b2d8cc6 commit 8f0c6bb

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

pkg-py/src/querychat/_datasource.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,26 @@ def __init__(self, df: IntoFrame, table_name: str):
115115
Name of the table in SQL queries
116116
117117
"""
118-
self._conn = duckdb.connect(database=":memory:")
119118
self._df = nw.from_native(df)
120119
self.table_name = table_name
121-
# TODO(@gadenbuie): If the data frame is already SQL-backed, maybe we shouldn't be making a new copy here.
120+
121+
self._conn = duckdb.connect(database=":memory:")
122+
# TODO(@gadenbuie): What if the data frame is already SQL-backed?
122123
self._conn.register(table_name, self._df.lazy().collect().to_pandas())
124+
self._conn.execute("""
125+
-- extensions: lock down supply chain + auto behaviors
126+
SET allow_community_extensions = false;
127+
SET allow_unsigned_extensions = false;
128+
SET autoinstall_known_extensions = false;
129+
SET autoload_known_extensions = false;
130+
131+
-- external I/O: block file/database/network access from SQL
132+
SET enable_external_access = false;
133+
SET disabled_filesystems = 'LocalFileSystem';
134+
135+
-- freeze configuration so user SQL can't relax anything
136+
SET lock_configuration = true;
137+
""")
123138

124139
def get_db_type(self) -> str:
125140
"""

pkg-r/R/DataSource.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,33 @@ DataFrameSource <- R6::R6Class(
163163
# Create in-memory connection and register the data frame
164164
if (engine == "duckdb") {
165165
check_installed("duckdb")
166+
166167
private$conn <- DBI::dbConnect(duckdb::duckdb(), dbdir = ":memory:")
168+
167169
duckdb::duckdb_register(
168170
private$conn,
169171
table_name,
170172
df,
171173
experimental = FALSE
172174
)
175+
176+
DBI::dbExecute(
177+
private$conn,
178+
r"(
179+
-- extensions: lock down supply chain + auto behaviors
180+
SET allow_community_extensions = false;
181+
SET allow_unsigned_extensions = false;
182+
SET autoinstall_known_extensions = false;
183+
SET autoload_known_extensions = false;
184+
185+
-- external I/O: block file/database/network access from SQL
186+
SET enable_external_access = false;
187+
SET disabled_filesystems = 'LocalFileSystem';
188+
189+
-- freeze configuration so user SQL can't relax anything
190+
SET lock_configuration = true;
191+
)"
192+
)
173193
} else if (engine == "sqlite") {
174194
check_installed("RSQLite")
175195
private$conn <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")

0 commit comments

Comments
 (0)