Skip to content

Commit e7ce7c6

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2: SQLite3: add DEFENSIVE config for SQLite >= 3.26.0 as a mitigation strategy against potential security flaws
2 parents 6818ca3 + e93259b commit e7ce7c6

File tree

6 files changed

+75
-0
lines changed

6 files changed

+75
-0
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ PHP NEWS
2626
- sodium:
2727
. Fixed bug #77646 (sign_detached() strings not terminated). (Frank)
2828

29+
- SQLite3:
30+
. Added sqlite3.defensive INI directive. (BohwaZ)
31+
2932
- Standard:
3033
. Fixed bug #77664 (Segmentation fault when using undefined constant in
3134
custom wrapper). (Laruence)

ext/sqlite3/php_sqlite3.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern zend_module_entry sqlite3_module_entry;
2626

2727
ZEND_BEGIN_MODULE_GLOBALS(sqlite3)
2828
char *extension_dir;
29+
int dbconfig_defensive;
2930
ZEND_END_MODULE_GLOBALS(sqlite3)
3031

3132
#ifdef ZTS

ext/sqlite3/sqlite3.c

+9
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ static void php_sqlite3_error(php_sqlite3_db_object *db_obj, char *format, ...)
7979
*/
8080
PHP_INI_BEGIN()
8181
STD_PHP_INI_ENTRY("sqlite3.extension_dir", NULL, PHP_INI_SYSTEM, OnUpdateString, extension_dir, zend_sqlite3_globals, sqlite3_globals)
82+
#if SQLITE_VERSION_NUMBER >= 3026000
83+
STD_PHP_INI_ENTRY("sqlite3.defensive", "1", PHP_INI_SYSTEM, OnUpdateBool, dbconfig_defensive, zend_sqlite3_globals, sqlite3_globals)
84+
#endif
8285
PHP_INI_END()
8386
/* }}} */
8487

@@ -164,6 +167,12 @@ PHP_METHOD(sqlite3, open)
164167
sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, NULL);
165168
}
166169

170+
#if SQLITE_VERSION_NUMBER >= 3026000
171+
if (SQLITE3G(dbconfig_defensive)) {
172+
sqlite3_db_config(db_obj->db, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
173+
}
174+
#endif
175+
167176
if (fullpath != filename) {
168177
efree(fullpath);
169178
}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
SQLite3 defensive mode ini setting
3+
--SKIPIF--
4+
<?php require_once(__DIR__ . '/skipif.inc');
5+
6+
if (SQLite3::version()['versionNumber'] < 3026000) {
7+
die("skip: sqlite3 library version < 3.26: no support for defensive mode");
8+
}
9+
10+
?>
11+
--INI--
12+
sqlite3.defensive=On
13+
--FILE--
14+
<?php
15+
16+
$db = new SQLite3(':memory:');
17+
var_dump($db->exec('CREATE TABLE test (a, b);'));
18+
19+
// This does not generate an error!
20+
var_dump($db->exec('PRAGMA writable_schema = ON;'));
21+
var_dump($db->querySingle('PRAGMA writable_schema;'));
22+
23+
// Should be 1
24+
var_dump($db->querySingle('SELECT COUNT(*) FROM sqlite_master;'));
25+
26+
// Should generate an error!
27+
var_dump($db->querySingle('DELETE FROM sqlite_master;'));
28+
29+
// Should still be 1
30+
var_dump($db->querySingle('SELECT COUNT(*) FROM sqlite_master;'));
31+
?>
32+
--EXPECTF--
33+
bool(true)
34+
bool(true)
35+
int(1)
36+
int(1)
37+
38+
Warning: SQLite3::querySingle(): Unable to prepare statement: 1, table sqlite_master may not be modified in %s on line %d
39+
bool(false)
40+
int(1)

php.ini-development

+11
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,19 @@ cli_server.color = On
10041004
;intl.use_exceptions = 0
10051005

10061006
[sqlite3]
1007+
; Directory pointing to SQLite3 extensions
1008+
; http://php.net/sqlite3.extension-dir
10071009
;sqlite3.extension_dir =
10081010

1011+
; SQLite defensive mode flag (only available from SQLite 3.26+)
1012+
; When the defensive flag is enabled, language features that allow ordinary
1013+
; SQL to deliberately corrupt the database file are disabled. This forbids
1014+
; writing directly to the schema, shadow tables (eg. FTS data tables), or
1015+
; the sqlite_dbpage virtual table.
1016+
; https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
1017+
; (for older SQLite versions, this flag has no use)
1018+
sqlite3.defensive = 1
1019+
10091020
[Pcre]
10101021
; PCRE library backtracking limit.
10111022
; http://php.net/pcre.backtrack-limit

php.ini-production

+11
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,19 @@ cli_server.color = On
10111011
;intl.use_exceptions = 0
10121012

10131013
[sqlite3]
1014+
; Directory pointing to SQLite3 extensions
1015+
; http://php.net/sqlite3.extension-dir
10141016
;sqlite3.extension_dir =
10151017

1018+
; SQLite defensive mode flag (only available from SQLite 3.26+)
1019+
; When the defensive flag is enabled, language features that allow ordinary
1020+
; SQL to deliberately corrupt the database file are disabled. This forbids
1021+
; writing directly to the schema, shadow tables (eg. FTS data tables), or
1022+
; the sqlite_dbpage virtual table.
1023+
; https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
1024+
; (for older SQLite versions, this flag has no use)
1025+
sqlite3.defensive = 1
1026+
10161027
[Pcre]
10171028
; PCRE library backtracking limit.
10181029
; http://php.net/pcre.backtrack-limit

0 commit comments

Comments
 (0)