diff options
Diffstat (limited to 'www/security.html')
-rw-r--r-- | www/security.html | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/www/security.html b/www/security.html new file mode 100644 index 0000000..b4925c7 --- /dev/null +++ b/www/security.html @@ -0,0 +1,330 @@ +<!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 The 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; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<div class=fancy> +<div class=nosearch> +<div class="fancy_title"> +Defense Against The 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> +Consider setting the <a href="compile.html#max_allocation_size">SQLITE_MAX_ALLOCATION_SIZE</a> compile-time option +to something smaller than its default value of 2147483391 (0x7ffffeff). +A value of 100000000 (100 million) or even smaller would not be unreasonable, +depending on the application. + +</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=100000</a>" or some similarly +reasonable 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><p> +Note that SQLite uses its built-in printf() internally to help it +format the sql column in the <a href="schematab.html">sqlite_schema table</a>. For that reason, +no table, index, view, or trigger definition can be much larger than the +precision limit. You can set a precision limit of less than 100000, +but be careful that whatever precision limit you use is at least as +long as the longest CREATE statement in your schema. +</p></li> + +</ol> + +<a name="baddb"></a> + +<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><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/security.in?m=31415c3b0b33a336e">2022-11-07 14:28:05</a> UTC </small></i></p> + |