290 lines
13 KiB
HTML
290 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html><head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
<link href="sqlite.css" rel="stylesheet">
|
|
<title>Defense Against Dark Arts</title>
|
|
<!-- path= -->
|
|
</head>
|
|
<body>
|
|
<div class=nosearch>
|
|
<a href="index.html">
|
|
<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
|
|
</a>
|
|
<div><!-- IE hack to prevent disappearing logo --></div>
|
|
<div class="tagline desktoponly">
|
|
Small. Fast. Reliable.<br>Choose any three.
|
|
</div>
|
|
<div class="menu mainmenu">
|
|
<ul>
|
|
<li><a href="index.html">Home</a>
|
|
<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
|
|
<li class='wideonly'><a href='about.html'>About</a>
|
|
<li class='desktoponly'><a href="docs.html">Documentation</a>
|
|
<li class='desktoponly'><a href="download.html">Download</a>
|
|
<li class='wideonly'><a href='copyright.html'>License</a>
|
|
<li class='desktoponly'><a href="support.html">Support</a>
|
|
<li class='desktoponly'><a href="prosupport.html">Purchase</a>
|
|
<li class='search' id='search_menubutton'>
|
|
<a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
|
|
</ul>
|
|
</div>
|
|
<div class="menu submenu" id="submenu">
|
|
<ul>
|
|
<li><a href='about.html'>About</a>
|
|
<li><a href='docs.html'>Documentation</a>
|
|
<li><a href='download.html'>Download</a>
|
|
<li><a href='support.html'>Support</a>
|
|
<li><a href='prosupport.html'>Purchase</a>
|
|
</ul>
|
|
</div>
|
|
<div class="searchmenu" id="searchmenu">
|
|
<form method="GET" action="search">
|
|
<select name="s" id="searchtype">
|
|
<option value="d">Search Documentation</option>
|
|
<option value="c">Search Changelog</option>
|
|
</select>
|
|
<input type="text" name="q" id="searchbox" value="">
|
|
<input type="submit" value="Go">
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function toggle_div(nm) {
|
|
var w = document.getElementById(nm);
|
|
if( w.style.display=="block" ){
|
|
w.style.display = "none";
|
|
}else{
|
|
w.style.display = "block";
|
|
}
|
|
}
|
|
function toggle_search() {
|
|
var w = document.getElementById("searchmenu");
|
|
if( w.style.display=="block" ){
|
|
w.style.display = "none";
|
|
} else {
|
|
w.style.display = "block";
|
|
setTimeout(function(){
|
|
document.getElementById("searchbox").focus()
|
|
}, 30);
|
|
}
|
|
}
|
|
function div_off(nm){document.getElementById(nm).style.display="none";}
|
|
window.onbeforeunload = function(e){div_off("submenu");}
|
|
/* Disable the Search feature if we are not operating from CGI, since */
|
|
/* Search is accomplished using CGI and will not work without it. */
|
|
if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
|
|
document.getElementById("search_menubutton").style.display = "none";
|
|
}
|
|
/* Used by the Hide/Show button beside syntax diagrams, to toggle the */
|
|
function hideorshow(btn,obj){
|
|
var x = document.getElementById(obj);
|
|
var b = document.getElementById(btn);
|
|
if( x.style.display!='none' ){
|
|
x.style.display = 'none';
|
|
b.innerHTML='show';
|
|
}else{
|
|
x.style.display = '';
|
|
b.innerHTML='hide';
|
|
}
|
|
return false;
|
|
}
|
|
</script>
|
|
</div>
|
|
<div class=fancy>
|
|
<div class=nosearch>
|
|
<div class="fancy_title">
|
|
Defense Against Dark Arts
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h1 id="sqlite_always_validates_its_inputs"><span>1. </span>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><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.
|
|
|
|
</p><h2 id="untrusted_sql_inputs"><span>1.1. </span>Untrusted SQL Inputs</h2>
|
|
<p>
|
|
Applications that accept untrusted SQL inputs should take the following
|
|
precautions:
|
|
|
|
</p><ol>
|
|
<li><p>
|
|
Set the <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive">SQLITE_DBCONFIG_DEFENSIVE</a> 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.
|
|
|
|
</p></li><li><p>
|
|
Reduce the <a href="limits.html">limits</a> 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
|
|
<a href="c3ref/limit.html">sqlite3_limit()</a> 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:
|
|
|
|
</p><table border="1" cellspacing="0">
|
|
<tr><th>Limit Setting</th><th>Default Value</th><th>High-security Value
|
|
</th></tr><tr><td>LIMIT_LENGTH</td><td align="right">1,000,000,000</td><td align="right">1,000,000
|
|
</td></tr><tr><td>LIMIT_SQL_LENGTH</td><td align="right">1,000,000,000</td><td align="right">100,000
|
|
</td></tr><tr><td>LIMIT_COLUMN</td><td align="right">2,000</td><td align="right">100
|
|
</td></tr><tr><td>LIMIT_EXPR_DEPTH</td><td align="right">1,000</td><td align="right">10
|
|
</td></tr><tr><td>LIMIT_COMPOUND_SELECT</td><td align="right">500</td><td align="right">3
|
|
</td></tr><tr><td>LIMIT_VDBE_OP</td><td align="right">250,000,000</td><td align="right">25,000
|
|
</td></tr><tr><td>LIMIT_FUNCTION_ARG</td><td align="right">127</td><td align="right">8
|
|
</td></tr><tr><td>LIMIT_ATTACH</td><td align="right">10</td><td align="right">0
|
|
</td></tr><tr><td>LIMIT_LIKE_PATTERN_LENGTH</td><td align="right">50,000</td><td align="right">50
|
|
</td></tr><tr><td>LIMIT_VARIABLE_NUMBER</td><td align="right">999</td><td align="right">10
|
|
</td></tr><tr><td>LIMIT_TRIGGER_DEPTH</td><td align="right">1,000</td><td align="right">10
|
|
</td></tr></table>
|
|
|
|
</li><li><p>
|
|
Consider using the <a href="c3ref/set_authorizer.html">sqlite3_set_authorizer()</a> 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.
|
|
|
|
</p></li><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
|
|
<a href="c3ref/progress_handler.html">sqlite3_progress_handler()</a> 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 <a href="c3ref/interrupt.html">sqlite3_interrupt()</a> when
|
|
the timer goes off to prevent the SQL statement from running forever.
|
|
|
|
</p></li><li><p>
|
|
Limit the maximum amount of memory that SQLite will allocate using
|
|
the <a href="c3ref/hard_heap_limit64.html">sqlite3_hard_heap_limit64()</a> interface. This helps prevent
|
|
denial-of-service attacks. To find out how much heap space an
|
|
application actually needs, run the it against typical inputs and
|
|
then measure the maximum instantaneous memory usage with the
|
|
<a href="c3ref/memory_highwater.html">sqlite3_memory_highwater()</a> interface. Set the hard heap limit
|
|
to the maximum observed instantaneous memory usage plus some margin.
|
|
|
|
</p></li><li><p>
|
|
For embedded systems, consider compiling SQLite with the
|
|
<a href="compile.html#enable_memsys5">-DSQLITE_ENABLE_MEMSYS5</a> option and then providing SQLite with
|
|
a fixed chunk of memory to use as its heap via the
|
|
<a href="c3ref/config.html">sqlite3_config</a>(<a href="c3ref/c_config_covering_index_scan.html#sqliteconfigheap">SQLITE_CONFIG_HEAP</a>) 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.
|
|
|
|
<a name="precisionlimit"></a>
|
|
</p></li><li><p>
|
|
To control memory usage in the <a href="lang_corefunc.html#printf">printf() SQL function</a>, compile
|
|
with "<a href="compile.html#printf_precision_limit">-DSQLITE_PRINTF_PRECISION_LIMIT=1000</a>" or some similar small value.
|
|
This #define limits the width and precision for %-substitutions in the
|
|
printf() function, and thus prevents a hostile SQL statement from
|
|
consuming large amounts of RAM via constructs such as
|
|
"<tt>printf('%1000000000s','hi')</tt>".
|
|
</p></li>
|
|
|
|
</ol>
|
|
|
|
<h2 id="untrusted_sqlite_database_files"><span>1.2. </span>Untrusted SQLite Database Files</h2>
|
|
|
|
<p>Applications that read or write SQLite database files of uncertain
|
|
provenance should take precautions enumerated below.
|
|
|
|
</p><p>Even if the application does not deliberately accept database files
|
|
from untrusted sources, beware of attacks in which a local
|
|
database file is altered. For best security, any database file which
|
|
might have ever been writable by an agent in a different security domain
|
|
should be treated as suspect.
|
|
|
|
</p><ol>
|
|
<li value="8"><p>
|
|
If the application includes any <a href="appfunc.html">custom SQL functions</a> or
|
|
<a href="vtab.html#customvtab">custom virtual tables</a> that have side effects or that might leak
|
|
privileged information, then the application should use one or more
|
|
of the techniques below to prevent a maliciously crafted database
|
|
schema from surreptitiously running those SQL functions and/or
|
|
virtual tables for nefarious purposes:
|
|
</p><ol type="a">
|
|
<li> Invoke <a href="c3ref/db_config.html">sqlite3_db_config</a>(db,<a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigtrustedschema">SQLITE_DBCONFIG_TRUSTED_SCHEMA</a>,0,0)
|
|
on each <a href="c3ref/sqlite3.html">database connection</a> as soon as it is opened.
|
|
</li><li> Run the <a href="pragma.html#pragma_trusted_schema">PRAGMA trusted_schema=OFF</a> statement on each database connection
|
|
as soon as it is opened.
|
|
</li><li> Compile SQLite using the <a href="compile.html#trusted_schema">-DSQLITE_TRUSTED_SCHEMA=0</a> compile-time option.
|
|
</li><li> Disable the surreptitious use of custom SQL functions and virtual tables
|
|
by setting the <a href="c3ref/c_deterministic.html#sqlitedirectonly">SQLITE_DIRECTONLY</a> flag on all custom SQL functions and
|
|
the <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly">SQLITE_VTAB_DIRECTONLY</a> flag on all custom virtual tables.
|
|
</li></ol>
|
|
|
|
</li><li><p>
|
|
If the application does not use triggers or views, consider disabling the
|
|
unused capabilities with:
|
|
</p><blockquote><pre>
|
|
<a href="c3ref/db_config.html">sqlite3_db_config</a>(db,<a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenabletrigger">SQLITE_DBCONFIG_ENABLE_TRIGGER</a>,0,0);
|
|
<a href="c3ref/db_config.html">sqlite3_db_config</a>(db,<a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigenableview">SQLITE_DBCONFIG_ENABLE_VIEW</a>,0,0);
|
|
</pre></blockquote>
|
|
|
|
</li></ol>
|
|
|
|
<p>
|
|
For reading database files that are unusually high-risk, such as database
|
|
files that are received from remote machines, and possibly from anonymous
|
|
contributors, the following extra precautions
|
|
might be justified. These added defenses come with performance costs,
|
|
however, and so may not be appropriate in every situation:
|
|
|
|
</p><ol>
|
|
<li value="10"><p>
|
|
Run <a href="pragma.html#pragma_integrity_check">PRAGMA integrity_check</a> or <a href="pragma.html#pragma_quick_check">PRAGMA quick_check</a> 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.
|
|
|
|
</p></li><li><p>
|
|
Enable the <a href="pragma.html#pragma_cell_size_check">PRAGMA cell_size_check=ON</a> setting.
|
|
</p><p>
|
|
|
|
</p></li><li><p>
|
|
Do not enable memory-mapped I/O.
|
|
In other words, make sure that <a href="pragma.html#pragma_mmap_size">PRAGMA mmap_size=0</a>.
|
|
</p></li></ol>
|
|
|
|
|
|
<h1 id="summary"><span>2. </span>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.
|
|
</p>
|