summaryrefslogtreecommitdiffstats
path: root/www/security.html
diff options
context:
space:
mode:
Diffstat (limited to 'www/security.html')
-rw-r--r--www/security.html330
1 files changed, 330 insertions, 0 deletions
diff --git a/www/security.html b/www/security.html
new file mode 100644
index 0000000..b84b6f4
--- /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="9"><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="11"><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=a75becf16a">2024-01-16 14:06:27</a> UTC </small></i></p>
+