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