Documentation Source Text

Artifact Content
Login

Artifact ce5da8f472aa8e81c2a1811a8e23834aab44764c66ca562c6a663064eb18d0e6:


<title>Defense Against Dark Arts</title>
<tcl>hd_keywords security {attack resistance} \
  {defense against dark arts}</tcl>
<fancy_format>

<h1>SQLite Always Validates Its Inputs</h1>

<p>
SQLite should never crash, overflow a buffer, leak memory,
or exhibit any other harmful behavior, even when presented with
maliciously malformed SQL inputs or database files.  SQLite should
always detect erroneous inputs and raise an error, not crash or
corrupt memory.
Any malfunction caused by an SQL input or database file
is considered a serious bug and will be promptly addressed when
brought to the attention of the SQLite developers.  SQLite is
extensively fuzz-tested to help ensure that it is resistant
to these kinds of errors.

<p>
Nevertheless, bugs happen.
If you are writing an application that sends untrusted SQL inputs
or database files to SQLite, there are additional steps you can take
to help reduce the attack surface and
prevent zero-day exploits caused by undetected bugs.

<h2>Untrusted SQL Inputs</h2>
<p>
Applications that accept untrusted SQL inputs should take the following
precautions:

<ol>
<li><p>
Set the [SQLITE_DBCONFIG_DEFENSIVE] flag.
This prevents ordinary SQL statements from deliberately corrupting the 
database file.  SQLite should be proof against attacks that involve both
malicious SQL inputs and a maliciously corrupted database file at the
same time.  Nevertheless, denying a script-only attacker access to 
corrupt database inputs provides an extra layer of defense.

<li><p>
Reduce the [limits] that SQLite imposes on inputs.  This can help prevent
denial of service attacks and other kinds of mischief that can occur
as a result of unusually large inputs.  You can do this either at compile-time
using -DSQLITE_MAX_... options, or at run-time using the
[sqlite3_limit()] interface.  Most applications can reduce limits
dramatically without impacting functionality.  The table below
provides some suggestions, though exact values will vary depending
on the application:

<table border="1" cellspacing="0">
<tr><th>Limit Setting<th>Default Value<th>High-security Value
<tr><td>LIMIT_LENGTH<td align="right">1,000,000,000<td align="right">1,000,000
<tr><td>LIMIT_SQL_LENGTH<td align="right">1,000,000,000<td align="right">100,000
<tr><td>LIMIT_COLUMN<td align="right">2,000<td align="right">100
<tr><td>LIMIT_EXPR_DEPTH<td align="right">1,000<td align="right">10
<tr><td>LIMIT_COMPOUND_SELECT<td align="right">500<td align="right">3
<tr><td>LIMIT_VDBE_OP<td align="right">250,000,000<td align="right">25,000
<tr><td>LIMIT_FUNCTION_ARG<td align="right">127<td align="right">8
<tr><td>LIMIT_ATTACH<td align="right">10<td align="right">0
<tr><td>LIMIT_LIKE_PATTERN_LENGTH<td align="right">50,000<td align="right">50
<tr><td>LIMIT_VARIABLE_NUMBER<td align="right">999<td align="right">10
<tr><td>LIMIT_TRIGGER_DEPTH<td align="right">1,000<td align="right">10
</table>

<li><p>
Consider using the [sqlite3_set_authorizer()] interface to limit
the scope of SQL that will be processed.  For example, an application
that does not need to change the database schema might add an
sqlite3_set_authorizer() callback that causes any CREATE or DROP
statement to fail.

<li><p>
The SQL language is very powerful, and so it is always possible for
malicious SQL inputs (or erroneous SQL inputs caused by an application
bug) to submit SQL that runs for a very long time.  To prevent this
from becoming a denial-of-service attack, consider using the
[sqlite3_progress_handler()] interface to invoke a callback periodically
as each SQL statement runs, and have that callback return non-zero to
abort the statement if the statement runs for too long.  Alternatively,
set a timer in a separate thread and invoke [sqlite3_interrupt()] when
the timer goes off to prevent the SQL statement from running forever.

<li><p>
In extreme cases, consider compiling SQLite with the
[-DSQLITE_ENABLE_MEMSYS5] option and then providing SQLite with
a fixed chunk of memory to use as its heap via the
[sqlite3_config]([SQLITE_CONFIG_HEAP]) interface. This will
prevent malicious SQL from executing a denial-of-service attack
by using an excessive amount of memory. If (say) 5 MB of memory
is provided for SQLite to use, once that much has been consumed,
SQLite will start returning SQLITE_NOMEM errors, rather than
soaking up memory needed by other parts of the application.
This also sandboxes SQLite's memory so that a write-after-free
error in some other part of the application will not cause
problems for SQLite, or vice versa.
</ol>

<h2>Untrusted SQLite Database Files</h2>

<p>Applications that accept untrusted database files should do the following:

<ol>
<li value="6"><p>
Run [PRAGMA integrity_check] or [PRAGMA quick_check] on the database
as the first SQL statement after opening the database files and
prior to running any other SQL statements.  Reject and refuse to
process any database file containing errors.

<li><p>
Enable the [PRAGMA cell_size_check=ON] setting.

<li><p>
Do not enable memory-mapped I/O.
In other words, make sure that [PRAGMA mmap_size=0].

<li><p>
A malicously crafted database might be able to inject SQL by defining new
[CREATE TRIGGER|triggers] or [CREATE VIEW|views] in the schema that the
application does not anticipate.
Therefore, applications that read untrusted databases might want to 
scan the [sqlite_master] table to look for unexpected triggers and/or views
and might also want to deploy the SQL defense techniques described in
the previous section.
</ol>

<h1>Summary</h1>

<p>
The precautions above are not required in order to use SQLite safely
with potentially hostile inputs.
However, they do provide an extra layer of defense against zero-day
exploits and are encouraged for applications that pass data from
untrusted sources into SQLite.