Small. Fast. Reliable.
Choose any three.

About Sitemap Documentation Download License News Developers Support

A security audit for SQLite consists of two components. First, there is a check for common errors that often lead to security problems. Second, an attempt is made to construct a proof that SQLite has certain desirable security properties.

## Part I: Things to check

Scan all source code and check for the following common errors:

1. Verify that the destination buffer is large enough to hold its result in every call to the following routines:

   - strcpy()
   - strncpy()
   - strcat()
   - memcpy()
   - memset()
   - memmove()
   - bcopy()
   - sprintf()
   - scanf()

2. Verify that pointers returned by subroutines are not NULL before using the pointers. In particular, make sure the return values for the following routines are checked before they are used:

   - malloc()
   - realloc()
   - sqliteMalloc()
   - sqliteRealloc()
   - sqliteStrDup()
   - sqliteStrNDup()
   - sqliteExpr()
   - sqliteExprFunction()
   - sqliteExprListAppend()
   - sqliteResultSetOfSelect()
   - sqliteIdListAppend()
   - sqliteSrcListAppend()
   - sqliteSelectNew()
   - sqliteTableNameToTable()
   - sqliteTableTokenToSrcList()
   - sqliteWhereBegin()
   - sqliteFindTable()
   - sqliteFindIndex()
   - sqliteTableNameFromToken()
   - sqliteGetVdbe()
   - sqlite_mprintf()
   - sqliteExprDup()
   - sqliteExprListDup()
   - sqliteSrcListDup()
   - sqliteIdListDup()
   - sqliteSelectDup()
   - sqliteFindFunction()
   - sqliteTriggerSelectStep()
   - sqliteTriggerInsertStep()
   - sqliteTriggerUpdateStep()
   - sqliteTriggerDeleteStep()

3. On all functions and procedures, verify that pointer parameters are not NULL before dereferencing those parameters.

4. Check to make sure that temporary files are opened safely: that the process will not overwrite an existing file when opening the temp file and that another process is unable to substitute a file for the temp file being opened.

## Part II: Things to prove

Prove that SQLite exhibits the characteristics outlined below:

1. The following are preconditions:

   - Z is an arbitrary-length NUL-terminated string.
   - An existing SQLite database has been opened. The return value from the call to sqlite_open() is stored in the variable db.
   - The database contains at least one table of the form:

     >     CREATE TABLE t1(a CLOB);

   - There are no user-defined functions other than the standard build-in functions.

   The following statement of C code is executed:

   >     sqlite_exec_printf(
   >        db,
   >        "INSERT INTO t1(a) VALUES('%q');",
   >        0, 0, 0, Z
   >     );

   Prove the following are true for all possible values of string Z:

   1. The call to sqlite_exec_printf() will return in a length of time that is a polynomial in strlen(Z). It might return an error code but it will not crash.

   2. At most one new row will be inserted into table t1.

   3. No preexisting rows of t1 will be deleted or modified.

   4. No tables other than t1 will be altered in any way.

   5. No preexisting files on the host computers filesystem, other than the database file itself, will be deleted or modified.

   6. For some constants K1 and K2, if at least K1*strlen(Z) + K2 bytes of contiguous memory are available to malloc(), then the call to sqlite_exec_printf() will not return SQLITE_NOMEM.

2. The following are preconditions:

   - Z is an arbitrary-length NUL-terminated string.
   - An existing SQLite database has been opened. The return value from the call to sqlite_open() is stored in the variable db.
   - There exists a callback function cb() that appends all information passed in through its parameters into a single data buffer called Y.
   - There are no user-defined functions other than the standard build-in functions.

   The following statement of C code is executed:

   >     sqlite_exec(db, Z, cb, 0, 0);

   Prove the following are true for all possible values of string Z:

   1. The call to sqlite_exec() will return in a length of time which is a polynomial in strlen(Z). It might return an error code but it will not crash.

   2. After sqlite_exec() returns, the buffer Y will not contain any content from any preexisting file on the host computers file system, except for the database file.

   3. After the call to sqlite_exec() returns, the database file will still be well-formed. It might not contain the same data, but it will still be a properly constructed SQLite database file.

   4. No preexisting files on the host computers filesystem, other than the database file itself, will be deleted or modified.

   5. For some constants K1 and K2, if at least K1*strlen(Z) + K2 bytes of contiguous memory are available to malloc(), then the call to sqlite_exec() will not return SQLITE_NOMEM.

This page last modified 2007/11/12 14:15:19 UTC