SQLite has no server process by default, so security is mostly about file access, key handling, and application behavior. This guide reflects security best practices for SQLite 3.51.2+.
# Set proper ownership and permissions
sudo chown app:app /srv/myapp/data/app.db
sudo chmod 640 /srv/myapp/data/app.db
# Also apply to WAL and SHM files
sudo chown app:app /srv/myapp/data/app.db-*
sudo chmod 640 /srv/myapp/data/app.db-*
sudo install -d -o app:app -m 750 /srv/myapp/data
SQLite is embedded in the application process, so injection protection is an app responsibility.
For applications that must execute untrusted SQL, use these security pragmas:
-- Prevent SQL from corrupting the database
PRAGMA recursive_triggers = OFF;
-- Limit query complexity
PRAGMA max_page_count = 1073741823; -- Max database size
PRAGMA mmap_size = 0; -- Disable memory mapping for untrusted data
Implement an authorizer to restrict SQL operations:
int auth_callback(void *user_data, int action, const char *arg1,
const char *arg2, const char *arg3, const char *arg4) {
// Return SQLITE_OK to allow, SQLITE_DENY to deny
// Customize based on your security requirements
}
sqlite3_set_authorizer(db, auth_callback, NULL);
SQLite does not provide built-in transparent encryption in standard builds.
Full-disk encryption (LUKS/dm-crypt) for host-level protection:
# Example LUKS setup for database partition
sudo cryptsetup luksFormat /dev/sdX
sudo cryptsetup luksOpen /dev/sdX encrypted_db
sudo mkfs.ext4 /dev/mapper/encrypted_db
SQLite Encryption Extension (SEE) - Proprietary solution from SQLite authors:
SQLCipher - Open-source solution with 256-bit AES encryption:
Application-level encryption - Encrypt data before storing in SQLite.
PRAGMA integrity_check;).# Create encrypted backup
sqlite3 /srv/myapp/data/app.db ".backup '| gpg --encrypt --recipient admin@company.com > /backups/app-$(date +%F).db.gpg'"
# Or compress and encrypt
sqlite3 /srv/myapp/data/app.db ".backup '| gzip | gpg --encrypt --recipient admin@company.com > /backups/app-$(date +%F).db.gz.gpg'"
# Example systemd service with resource limits
[Service]
User=appuser
MemoryMax=512M
TasksMax=100
When processing untrusted database files or SQL:
-- Disable potentially dangerous features
PRAGMA trusted_schema = OFF; -- Don't trust schema from db file
PRAGMA cell_size_check = ON; -- Extra validation
PRAGMA mmap_size = 0; -- Disable memory mapping
PRAGMA temp_store = MEMORY; -- Force temp data to memory
-wal, -shm) with sensitive data.# Check for orphaned WAL/SHM files
find /srv/myapp/data -name "*.db-*" -mtime +1 -exec ls -la {} \;
#!/bin/bash
# Simple audit trail for database access
LOG_FILE="/var/log/sqlite-access.log"
echo "$(date): $(whoami) accessed $(basename $1)" >> $LOG_FILE
With SQLite 3.51.2+, you can leverage new security features:
SQLITE_DBCONFIG_DEFENSIVE to prevent SQL statements from corrupting the databasePRAGMA trusted_schema=OFF when opening untrusted database filesMonitor these aspects of your SQLite deployment: