Skip to content

Commit eac29a0

Browse files
committed
db: add security pragmas and STRICT tables for developer mode
Enable trusted_schema=OFF and cell_size_check=ON pragmas when running in developer mode for enhanced security and debugging. Add STRICT keyword to CREATE TABLE statements in developer mode for improved type safety with SQLite 3.37.0+. Add missing VARCHAR and INT type conversions in sql-rewrite.py. Addresses feedback from issue #7913.
1 parent 2e2a085 commit eac29a0

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

db/db_sqlite3.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,16 +205,44 @@ static bool db_sqlite3_setup(struct db *db, bool create)
205205
"PRAGMA foreign_keys = ON;", -1, &stmt, NULL);
206206
err = sqlite3_step(stmt);
207207
sqlite3_finalize(stmt);
208-
return err == SQLITE_DONE;
208+
209+
if (err != SQLITE_DONE)
210+
return false;
211+
212+
if (db->developer) {
213+
sqlite3_prepare_v2(conn2sql(db->conn),
214+
"PRAGMA trusted_schema = OFF;", -1, &stmt, NULL);
215+
sqlite3_step(stmt);
216+
sqlite3_finalize(stmt);
217+
218+
sqlite3_prepare_v2(conn2sql(db->conn),
219+
"PRAGMA cell_size_check = ON;", -1, &stmt, NULL);
220+
sqlite3_step(stmt);
221+
sqlite3_finalize(stmt);
222+
}
223+
224+
return true;
209225
}
210226

211227
static bool db_sqlite3_query(struct db_stmt *stmt)
212228
{
213229
sqlite3_stmt *s;
214230
sqlite3 *conn = conn2sql(stmt->db->conn);
215231
int err;
232+
const char *query = stmt->query->query;
233+
char *modified_query = NULL;
234+
235+
if (stmt->db->developer &&
236+
strncasecmp(query, "CREATE TABLE", 12) == 0 &&
237+
!strstr(query, "STRICT")) {
238+
modified_query = tal_fmt(stmt, "%s STRICT", query);
239+
query = modified_query;
240+
}
241+
242+
err = sqlite3_prepare_v2(conn, query, -1, &s, NULL);
216243

217-
err = sqlite3_prepare_v2(conn, stmt->query->query, -1, &s, NULL);
244+
if (modified_query)
245+
tal_free(modified_query);
218246

219247
for (size_t i=0; i<stmt->query->placeholders; i++) {
220248
struct db_binding *b = &stmt->bindings[i];

devtools/sql-rewrite.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def rewrite_single(self, query):
4545
r'BIGINT': 'INTEGER',
4646
r'BIGINTEGER': 'INTEGER',
4747
r'BIGSERIAL': 'INTEGER',
48+
r'VARCHAR(?:\(\d+\))?': 'TEXT',
49+
r'\bINT\b': 'INTEGER',
4850
r'CURRENT_TIMESTAMP\(\)': "strftime('%s', 'now')",
4951
r'INSERT INTO[ \t]+(.*)[ \t]+ON CONFLICT.*DO NOTHING;': 'INSERT OR IGNORE INTO \\1;',
5052
# Rewrite "decode('abcd', 'hex')" to become "x'abcd'"

tests/test_db.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,3 +642,22 @@ def test_channel_htlcs_id_change(bitcoind, node_factory):
642642
# Make some HTLCS
643643
for amt in (100, 500, 1000, 5000, 10000, 50000, 100000):
644644
l1.pay(l3, amt)
645+
646+
647+
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "STRICT tables are SQLite3 specific")
648+
def test_sqlite_strict_mode(node_factory):
649+
"""Test that STRICT is appended to CREATE TABLE in developer mode."""
650+
l1 = node_factory.get_node(options={'developer': None})
651+
652+
# Query sqlite_master to check table definitions
653+
tables = l1.db_query("SELECT name, sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
654+
655+
strict_tables = [t for t in tables if t['sql'] and 'STRICT' in t['sql']]
656+
assert len(strict_tables) > 0, f"Expected at least one STRICT table in developer mode, found none out of {len(tables)}"
657+
658+
# Check specific tables we know should be STRICT in developer mode
659+
known_strict_tables = ['version', 'forwards', 'payments', 'local_anchors', 'addresses']
660+
for table_name in known_strict_tables:
661+
table_sql = next((t['sql'] for t in tables if t['name'] == table_name), None)
662+
if table_sql:
663+
assert 'STRICT' in table_sql, f"Expected table '{table_name}' to be STRICT in developer mode"

0 commit comments

Comments
 (0)