Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Every database connection now has a default authorizer, which calls out to an operation-specific authorizer if needed. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | sec2020 |
| Files: | files | file ages | folders |
| SHA3-256: |
f98ef3c1034e1d8d5174c4d8d1144858 |
| User & Date: | drh 2020-08-17 19:59:55.907 |
Context
|
2020-08-17
| ||
| 20:03 | Identify security-sensitive settings. check-in: 3bccd7fff2 user: drh tags: sec2020 | |
| 19:59 | Every database connection now has a default authorizer, which calls out to an operation-specific authorizer if needed. check-in: f98ef3c103 user: drh tags: sec2020 | |
| 18:57 | Enhance the db_prepare() and db_static_prepare() utility routines so that they throw an error if handed more than one SQL statement. This might help prevent SQL injection attacks. check-in: be0d95aded user: drh tags: sec2020 | |
Changes
Changes to src/db.c.
| ︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
const char *zStartFile; /* File in which transaction was started */
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
| > > > | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
const char *zStartFile; /* File in which transaction was started */
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
char protectUser; /* Prevent changes to the USER table */
char protectSensitive; /* Prevent changes to sensitive CONFIG entries */
char protectConfig; /* Prevent any changes to the CONFIG table */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
|
| ︙ | ︙ | |||
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
db.aHook[i].xHook = xS;
}
}
db.aHook[db.nCommitHook].sequence = sequence;
db.aHook[db.nCommitHook].xHook = x;
db.nCommitHook++;
}
/*
** Set or unset the query authorizer callback function
*/
void db_set_authorizer(
int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg,
const char *zName /* for tracing */
){
if( db.xAuth ){
fossil_panic("multiple active db_set_authorizer() calls");
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
db.aHook[i].xHook = xS;
}
}
db.aHook[db.nCommitHook].sequence = sequence;
db.aHook[db.nCommitHook].xHook = x;
db.nCommitHook++;
}
/*
** Every Fossil database connection automatically registers the following
** overarching authenticator callback, and leaves it registered for the
** duration of the connection. This authenticator will call any
** sub-authenticators that are registered using db_set_authorizer().
*/
static int db_top_authorizer(
void *pNotUsed,
int eCode,
const char *z0,
const char *z1,
const char *z2,
const char *z3
){
int rc = SQLITE_OK;
switch( eCode ){
case SQLITE_INSERT:
case SQLITE_UPDATE:
case SQLITE_DELETE: {
if( db.protectUser && sqlite3_stricmp(z0,"user")==0 ){
rc = SQLITE_DENY;
}else if( db.protectConfig &&
(sqlite3_stricmp(z0,"config")==0 ||
sqlite3_stricmp(z0,"global_config")==0) ){
rc = SQLITE_DENY;
}
break;
}
case SQLITE_DROP_TEMP_TRIGGER: {
if( db.protectSensitive ){
rc = SQLITE_DENY;
}
break;
}
}
if( db.xAuth && rc==SQLITE_OK ){
rc = db.xAuth(db.pAuthArg, eCode, z0, z1, z2, z3);
}
return rc;
}
/*
** Set or unset the query authorizer callback function
*/
void db_set_authorizer(
int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg,
const char *zName /* for tracing */
){
if( db.xAuth ){
fossil_panic("multiple active db_set_authorizer() calls");
}
db.xAuth = xAuth;
db.pAuthArg = pArg;
db.zAuthName = zName;
if( g.fSqlTrace ) fossil_trace("-- set authorizer %s\n", zName);
}
void db_clear_authorizer(void){
if( db.zAuthName && g.fSqlTrace ){
fossil_trace("-- discontinue authorizer %s\n", db.zAuthName);
}
db.xAuth = 0;
db.pAuthArg = 0;
db.zAuthName = 0;
}
#if INTERFACE
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
|
| ︙ | ︙ | |||
900 901 902 903 904 905 906 | sqlite3 *xdb; int rc; const char *zSql; va_list ap; xdb = db_open(zFileName ? zFileName : ":memory:"); sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0); | < < < | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 |
sqlite3 *xdb;
int rc;
const char *zSql;
va_list ap;
xdb = db_open(zFileName ? zFileName : ":memory:");
sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0);
rc = sqlite3_exec(xdb, zSchema, 0, 0, 0);
if( rc!=SQLITE_OK ){
db_err("%s", sqlite3_errmsg(xdb));
}
va_start(ap, zSchema);
while( (zSql = va_arg(ap, const char*))!=0 ){
rc = sqlite3_exec(xdb, zSql, 0, 0, 0);
|
| ︙ | ︙ | |||
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 |
db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
);
if( g.fSqlTrace ) sqlite3_trace_v2(db, SQLITE_TRACE_PROFILE, db_sql_trace, 0);
db_add_aux_functions(db);
re_add_sql_func(db); /* The REGEXP operator */
foci_register(db); /* The "files_of_checkin" virtual table */
sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 0, &rc);
return db;
}
/*
** Detaches the zLabel database.
*/
| > | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 |
db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
);
if( g.fSqlTrace ) sqlite3_trace_v2(db, SQLITE_TRACE_PROFILE, db_sql_trace, 0);
db_add_aux_functions(db);
re_add_sql_func(db); /* The REGEXP operator */
foci_register(db); /* The "files_of_checkin" virtual table */
sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 0, &rc);
sqlite3_set_authorizer(db, db_top_authorizer, db);
return db;
}
/*
** Detaches the zLabel database.
*/
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
449 450 451 452 453 454 455 456 457 |
char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
if( separateConnection ){
if( db_transaction_nesting_depth() ) db_end_transaction(0);
| > < < | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
if( separateConnection ){
if( db_transaction_nesting_depth() ) db_end_transaction(0);
db_init_database(g.zRepositoryName, zSql, 0);
}else{
db_multi_exec("%s", zSql/*safe-for-%s*/);
}
db_clear_authorizer();
fossil_free(zSql);
}
/*
|
| ︙ | ︙ |