SQLite

SQLite is an embedded, file-based database with no server or user accounts, so injection against it has a different shape from the client-server engines. Several traits matter.

There is no information_schema; the schema lives in sqlite_master (aliased sqlite_schema in newer versions), whose sql column stores each object's CREATE statement and therefore reveals column names directly. There is no SLEEP, so time-based inference uses a deliberately expensive expression such as randomblob(). SQLite is loosely typed, which makes UNION easy (type mismatches rarely block it) but breaks some error tricks from other engines: dividing by zero returns NULL rather than erroring, and casting a non-numeric string yields 0, so error-based injection must use primitives that genuinely raise an error.

Comments are -- and /* */. String concatenation is ||. Stacked queries depend on the API: sqlite3_exec runs multiple ;-separated statements, while a prepared statement runs only the first, so stacking is confirmed, not assumed.

The high-impact primitives are ATTACH DATABASE, which can write a file, and load_extension(), which loads a shared library for code execution but is disabled by default. There are no privilege levels inside SQLite: whatever the application's database handle can do, the injection can do.

Techniques#

References#

  • SQLite Documentation: sqlite_master, core functions, ATTACH, load_extension
  • OWASP Testing Guide: Testing for SQL Injection

Cookie Consent

We use cookies to enhance your experience. Learn more