Skip to main content
← All libraries
Database · C

How to fuzz SQLite

SQLite is in every smartphone, browser, and OS — a query parser bug is universally exploitable.

SQLite processes SQL strings and binary database files from untrusted sources in browsers, mobile apps, and desktop applications. Its hand-written SQL parser, query optimizer, and virtual table interface each represent dense bug surfaces; Google's OSS-Fuzz finds dozens of SQLite issues per year.

Common bug classes

  • Heap buffer overflow in SQL expression tree node allocation
  • Integer overflow in page size to memory map size arithmetic
  • Use-after-free in query optimizer constant-folding rewrite
  • Out-of-bounds read in B-tree page boundary validation
  • Null dereference on malformed sqlite3 file header magic

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer
  • Honggfuzz
  • Centipede

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <sqlite3.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  sqlite3 *db;
  if (sqlite3_open(":memory:", &db) != SQLITE_OK) return 0;
  char *errmsg = NULL;
  /* Run as SQL statement */
  char *sql = (char *)sqlite3_malloc((int)size + 1);
  if (sql) {
    memcpy(sql, data, size); sql[size] = '';
    sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (errmsg) sqlite3_free(errmsg);
    sqlite3_free(sql);
  }
  sqlite3_close(db);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Notable CVEs found by fuzzing

  • CVE-2022-35737
Start fuzzing SQLite on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.