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>
 |