/ Check-in [11d98414]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the SQLITE_DBCONFIG_DEFENSIVE flag.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 11d98414eac467affb0b3cf0c7e5cc3d43184fc2b6e7e898bb5277b51ea9e1fa
User & Date: drh 2018-11-05 19:37:30
Context
2018-11-07
11:56
Partially revert [3e1a2f661], as some test scripts require separate $presql and $dbconfig variables. check-in: cbf85284 user: dan tags: trunk
2018-11-05
23:01
Initial code to make shadow tables read-only to ordinary SQL. The now xShadowName method is added to the sqlite3_module object and is used to identify potential shadow tables. The SQLITE_PREPARE_SHADOW argument to sqlite3_prepare_v3() is defined. It is designed to permit writing to shadow tables, but is currently an unused placeholder. check-in: 31942b3d user: drh tags: read-only-shadow
20:37
Add preliminary version of "changesetfuzz" program. For fuzzing changeset data without creating corrupt changesets. check-in: 81ac8745 user: dan tags: changesetfuzz
19:37
Add the SQLITE_DBCONFIG_DEFENSIVE flag. check-in: 11d98414 user: drh tags: trunk
16:38
Eponymous virtual tables appear to exist in all schemas. This is an alternative and improved fix to the eponymous virtual table in trigger problem that was previously addressed by checkin [1fa74930ab56171e]. check-in: b8d35c4a user: drh tags: trunk
2018-11-03
17:31
Correct the internal logic for SQLITE_DBCONFIG_DEFENSIVE. Closed-Leaf check-in: 76094345 user: drh tags: dbconfig-defensive
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  3108   3108         pBt->usableSize = usableSize;
  3109   3109         pBt->pageSize = pageSize;
  3110   3110         freeTempSpace(pBt);
  3111   3111         rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
  3112   3112                                      pageSize-usableSize);
  3113   3113         return rc;
  3114   3114       }
  3115         -    if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
         3115  +    if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
  3116   3116         rc = SQLITE_CORRUPT_BKPT;
  3117   3117         goto page1_init_failed;
  3118   3118       }
  3119   3119       /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
  3120   3120       ** be less than 480. In other words, if the page size is 512, then the
  3121   3121       ** reserved space size cannot exceed 32. */
  3122   3122       if( usableSize<480 ){

Changes to src/build.c.

   790    790       assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT
   791    791                || (db->mDbFlags & DBFLAG_Vacuum)!=0);
   792    792       iDb = db->init.iDb;
   793    793       *pUnqual = pName1;
   794    794     }
   795    795     return iDb;
   796    796   }
          797  +
          798  +/*
          799  +** True if PRAGMA writable_schema is ON
          800  +*/
          801  +int sqlite3WritableSchema(sqlite3 *db){
          802  +  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
          803  +  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
          804  +               SQLITE_WriteSchema );
          805  +  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
          806  +               SQLITE_Defensive );
          807  +  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
          808  +               (SQLITE_WriteSchema|SQLITE_Defensive) );
          809  +  return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
          810  +}
   797    811   
   798    812   /*
   799    813   ** This routine is used to check if the UTF-8 string zName is a legal
   800    814   ** unqualified name for a new schema object (table, index, view or
   801    815   ** trigger). All names are legal except those that begin with the string
   802    816   ** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
   803    817   ** is reserved for internal use.
   804    818   */
   805    819   int sqlite3CheckObjectName(Parse *pParse, const char *zName){
   806    820     if( !pParse->db->init.busy && pParse->nested==0 
   807         -          && (pParse->db->flags & SQLITE_WriteSchema)==0
          821  +          && sqlite3WritableSchema(pParse->db)==0
   808    822             && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
   809    823       sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
   810    824       return SQLITE_ERROR;
   811    825     }
   812    826     return SQLITE_OK;
   813    827   }
   814    828   

Changes to src/dbpage.c.

   309    309     char *zErr = 0;
   310    310     const char *zSchema;
   311    311     int iDb;
   312    312     Btree *pBt;
   313    313     Pager *pPager;
   314    314     int szPage;
   315    315   
          316  +  if( pTab->db->flags & SQLITE_Defensive ){
          317  +    zErr = "read-only";
          318  +    goto update_fail;
          319  +  }
   316    320     if( argc==1 ){
   317    321       zErr = "cannot delete";
   318    322       goto update_fail;
   319    323     }
   320    324     pgno = sqlite3_value_int(argv[0]);
   321    325     if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
   322    326       zErr = "cannot insert";

Changes to src/delete.c.

    59     59     **      been specified.
    60     60     **
    61     61     ** In either case leave an error message in pParse and return non-zero.
    62     62     */
    63     63     if( ( IsVirtual(pTab) 
    64     64        && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
    65     65      || ( (pTab->tabFlags & TF_Readonly)!=0
    66         -     && (pParse->db->flags & SQLITE_WriteSchema)==0
    67         -     && pParse->nested==0 )
           66  +     && sqlite3WritableSchema(pParse->db)==0
           67  +     && pParse->nested==0)
    68     68     ){
    69     69       sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    70     70       return 1;
    71     71     }
    72     72   
    73     73   #ifndef SQLITE_OMIT_VIEW
    74     74     if( !viewOk && pTab->pSelect ){

Changes to src/main.c.

   831    831           { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
   832    832           { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
   833    833           { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
   834    834           { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
   835    835           { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
   836    836           { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
   837    837           { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
          838  +        { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
   838    839         };
   839    840         unsigned int i;
   840    841         rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
   841    842         for(i=0; i<ArraySize(aFlagOp); i++){
   842    843           if( aFlagOp[i].op==op ){
   843    844             int onoff = va_arg(ap, int);
   844    845             int *pRes = va_arg(ap, int*);

Changes to src/shell.c.in.

  5952   5952           { "enable_trigger",   SQLITE_DBCONFIG_ENABLE_TRIGGER         },
  5953   5953           { "fts3_tokenizer",   SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER  },
  5954   5954           { "load_extension",   SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION  },
  5955   5955           { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE       },
  5956   5956           { "enable_qpsg",      SQLITE_DBCONFIG_ENABLE_QPSG            },
  5957   5957           { "trigger_eqp",      SQLITE_DBCONFIG_TRIGGER_EQP            },
  5958   5958           { "reset_database",   SQLITE_DBCONFIG_RESET_DATABASE         },
         5959  +        { "defensive",        SQLITE_DBCONFIG_DEFENSIVE              },
  5959   5960       };
  5960   5961       int ii, v;
  5961   5962       open_db(p, 0);
  5962   5963       for(ii=0; ii<ArraySize(aDbConfig); ii++){
  5963   5964         if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
  5964   5965         if( nArg>=3 ){
  5965   5966           sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);

Changes to src/sqlite.h.in.

  2154   2154   ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
  2155   2155   ** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
  2156   2156   ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
  2157   2157   ** </ol>
  2158   2158   ** Because resetting a database is destructive and irreversible, the
  2159   2159   ** process requires the use of this obscure API and multiple steps to help
  2160   2160   ** ensure that it does not happen by accident.
         2161  +**
         2162  +** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
         2163  +** <dd>The SQLITE_DBCONFIG_DEFENSIVE option actives or deactivates the
         2164  +** "defensive" flag for a database connection.  When the defensive
         2165  +** flag is enabled, some obscure features of SQLite are disabled in order
         2166  +** to reduce the attack surface. Applications that run untrusted SQL
         2167  +** can activate this flag to reduce the risk of zero-day exploits.
         2168  +** <p>
         2169  +** Features disabled by the defensive flag include:
         2170  +** <ul>
         2171  +** <li>The [PRAGMA writable_schema=ON] statement.
         2172  +** <li>Writes to the [sqlite_dbpage] virtual table.
         2173  +** </ul>
         2174  +** New restrictions may be added in future releases.
         2175  +** <p>
         2176  +** To be clear: It should never be possible for hostile SQL to cause
         2177  +** arbitrary memory reads, memory leaks, buffer overflows, assertion
         2178  +** faults, arbitrary code execution, crashes, or other mischief, regardless
         2179  +** of the value of the defensive flag.  Any occurrance of these problems
         2180  +** is considered a serious bug and will be fixed promptly.  It is not
         2181  +** necessary to enable the defensive flag in order to make SQLite secure
         2182  +** against attack. The defensive flag merely provides an additional layer
         2183  +** of defense against unknown vulnerabilities.
  2161   2184   ** </dd>
  2162   2185   ** </dl>
  2163   2186   */
  2164   2187   #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
  2165   2188   #define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
  2166   2189   #define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
  2167   2190   #define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
  2168   2191   #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
  2169   2192   #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
  2170   2193   #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
  2171   2194   #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
  2172   2195   #define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
  2173   2196   #define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
  2174         -#define SQLITE_DBCONFIG_MAX                   1009 /* Largest DBCONFIG */
         2197  +#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
         2198  +#define SQLITE_DBCONFIG_MAX                   1010 /* Largest DBCONFIG */
  2175   2199   
  2176   2200   /*
  2177   2201   ** CAPI3REF: Enable Or Disable Extended Result Codes
  2178   2202   ** METHOD: sqlite3
  2179   2203   **
  2180   2204   ** ^The sqlite3_extended_result_codes() routine enables or disables the
  2181   2205   ** [extended result codes] feature of SQLite. ^The extended result

Changes to src/sqliteInt.h.

  1536   1536   #define SQLITE_CellSizeCk     0x00200000  /* Check btree cell sizes on load */
  1537   1537   #define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
  1538   1538   #define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
  1539   1539   #define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
  1540   1540   #define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
  1541   1541   #define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */
  1542   1542   #define SQLITE_NoSchemaError  0x08000000  /* Do not report schema parse errors*/
         1543  +#define SQLITE_Defensive      0x10000000  /* Input SQL is likely hostile */
  1543   1544   
  1544   1545   /* Flags used only if debugging */
  1545   1546   #define HI(X)  ((u64)(X)<<32)
  1546   1547   #ifdef SQLITE_DEBUG
  1547   1548   #define SQLITE_SqlTrace       HI(0x0001)  /* Debug print SQL as it executes */
  1548   1549   #define SQLITE_VdbeListing    HI(0x0002)  /* Debug listings of VDBE progs */
  1549   1550   #define SQLITE_VdbeTrace      HI(0x0004)  /* True to trace VDBE execution */
................................................................................
  4199   4200   CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
  4200   4201   CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
  4201   4202   int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
  4202   4203   Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
  4203   4204   Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
  4204   4205   Expr *sqlite3ExprSkipCollate(Expr*);
  4205   4206   int sqlite3CheckCollSeq(Parse *, CollSeq *);
         4207  +int sqlite3WritableSchema(sqlite3*);
  4206   4208   int sqlite3CheckObjectName(Parse *, const char *);
  4207   4209   void sqlite3VdbeSetChanges(sqlite3 *, int);
  4208   4210   int sqlite3AddInt64(i64*,i64);
  4209   4211   int sqlite3SubInt64(i64*,i64);
  4210   4212   int sqlite3MulInt64(i64*,i64);
  4211   4213   int sqlite3AbsInt32(int);
  4212   4214   #ifdef SQLITE_ENABLE_8_3_NAMES

Changes to src/test1.c.

  7552   7552       { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
  7553   7553       { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
  7554   7554       { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
  7555   7555       { "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
  7556   7556       { "QPSG",            SQLITE_DBCONFIG_ENABLE_QPSG },
  7557   7557       { "TRIGGER_EQP",     SQLITE_DBCONFIG_TRIGGER_EQP },
  7558   7558       { "RESET_DB",        SQLITE_DBCONFIG_RESET_DATABASE },
         7559  +    { "DEFENSIVE",       SQLITE_DBCONFIG_DEFENSIVE },
  7559   7560     };
  7560   7561     int i;
  7561   7562     int v;
  7562   7563     const char *zSetting;
  7563   7564     sqlite3 *db;
  7564   7565   
  7565   7566     if( objc!=4 ){

Changes to test/index.test.

   621    621   # little outside the focus of this test scripts, but this has got to be
   622    622   # tested somewhere.
   623    623   do_test index-18.1 {
   624    624     catchsql {
   625    625       CREATE TABLE sqlite_t1(a, b, c);
   626    626     }
   627    627   } {1 {object name reserved for internal use: sqlite_t1}}
          628  +do_test index-18.1.2 {
          629  +  sqlite3_db_config db DEFENSIVE 1
          630  +  catchsql {
          631  +    CREATE TABLE sqlite_t1(a, b, c);
          632  +  }
          633  +} {1 {object name reserved for internal use: sqlite_t1}}
          634  +sqlite3_db_config db DEFENSIVE 0
   628    635   do_test index-18.2 {
   629    636     catchsql {
   630    637       CREATE INDEX sqlite_i1 ON t7(c);
   631    638     }
   632    639   } {1 {object name reserved for internal use: sqlite_i1}}
   633    640   ifcapable view {
   634    641   do_test index-18.3 {