QoreDB LogoQoreDB
Back to blog
SecurityTechnical journal

QoreDB's Security Model: Threats and Countermeasures

Many discussions about the security of a database client start from the model of an online service, with multi-tenant authentication, network isolation, and centralized logs. QoreDB is not that product. It's a desktop application that runs on a developer's machine, reads their…

Raphaël – Creator of QoreDBRaphaël – Creator of QoreDB
5 min readUpdated Jul 18, 2026
QoreDB's Security Model: Threats and Countermeasures

Many discussions about the security of a database client start from the model of an online service, with multi-tenant authentication, network isolation, and centralized logs. QoreDB is not that product. It's a desktop application that runs on a developer's machine, reads their credentials, and talks directly to PostgreSQL, MySQL, MongoDB, SQLite, SQL Server, CockroachDB, Redis, and DuckDB engines. The threat model isn't that of a SaaS, and trying to copy it over would produce both too much friction and false guarantees.

This article describes how QoreDB reasons about its assets, the realistic threats for single-user desktop use, and the mechanisms that apply by design.

The assets to protect

Four categories of assets structure the model. The credentials (passwords, SSH keys, API tokens) are the most sensitive asset: they grant access to entire databases. The database data passes through the application for the duration of a query, is displayed, sometimes exported. The connection metadata (host, port, username) is less critical but informs an attacker about the target architecture. Finally, the local state (query history, recovery drafts, audit log, profiling data) can indirectly contain sensitive elements if it's mishandled.

This hierarchy guides the decisions: strong protection applies first to credentials and to mutations on the database, then to local persistence.

Keeping credentials out of reach of malware

The most mundane threat on a developer's machine is the siphoning of configuration files by a malicious binary. Old clients stored connections in plaintext in a JSON or a YAML. QoreDB delegates this storage to the operating system's keychain via the keyring crate. On macOS it's the Keychain, on Linux the Secret Service, on Windows the Credential Manager. No password is written to any file of the application.

This delegation has two consequences. First, access to secrets goes through the system's authentication mechanism (TouchID, password, PIN depending on the platform). Second, in memory, the strings containing secrets are wrapped in a Sensitive<String> type that automatically redacts their display in traces, logs, and debug output. A leak through logs becomes unlikely even in the event of a programming error.

Preventing accidental destruction

The most frequent threat, in real life, isn't an attacker: it's a tired developer who runs DROP TABLE users on the wrong connection. QoreDB addresses this risk with an explicit classification of connections: Development, Staging, Production. A connection labeled Production gets red borders throughout the interface, which makes any visual confusion between two tabs impossible.

Beyond the visual, the safety rules engine (src-tauri/src/interceptor/safety.rs) ships with a set of built-in rules. DROP and TRUNCATE are blocked in production. DELETE and UPDATE without a WHERE require an explicit confirmation. The Read-Only mode, independent of the environment, refuses any mutation at the backend level, not just in the UI.

The enforcement of these rules is centralized in the query interceptor, which avoids each Tauri command having to reimplement them. The critical paths (execute_query, mutation, maintenance, routines, triggers, sequences, database creation/deletion) all consult this engine before acting.

Keeping secrets out of the logs

A useful audit log must contain the text of the queries, otherwise it's useless for reconstructing an incident. But this text can contain a password (ALTER USER ... WITH PASSWORD '...'), a token, or a connection URI. QoreDB systematically redacts the content before persistence, via interceptor::redaction::redact_query.

The redaction is driver-aware. For SQL drivers, it replaces single-quoted literals, connection URIs, and the pairs password=, token=, secret=, api_key=. For MongoDB, it targets the sensitive JSON keys (password, token, credentials, authorization) and the mongodb+srv:// URIs. For Redis, it cleans the AUTH, CONFIG SET requirepass arguments and the bodies of EVAL scripts.

The same mechanism computes a stable fingerprint of the redacted query, which makes it possible to group slow queries by shape without ever comparing literals. The query history and the frontend error log, for their part, are opt-in and also go through a redaction layer before being written to disk.

Controlling what goes out to the network

QoreDB is local-first, but some features reach the network: sharing exports to a configurable endpoint, optional AI integrations, opt-in anonymous telemetry. Three mechanisms frame these outbound flows.

First mechanism: the webview's CSP. The tauri.conf.json file defines explicit allowlists for default-src, script-src, connect-src and the like. The frontend can't call arbitrary URLs in JavaScript: the request must go through the Rust backend, which applies its own validation.

Second mechanism: custom share providers are constrained to HTTPS, with an explicit exception for localhost, 127.0.0.1 and ::1. The providers' tokens are also stored in the system keyring, never in plaintext on disk.

Third mechanism: telemetry is opt-in. No outbound call leaves the application without an explicit user action, and query results are never sent to a third-party service, even for profiling: everything stays on the machine.

Reducing the build surface

The supply chain threat is real for any tool that connects to production databases. QoreDB responds by keeping a minimal dependency tree, publishing a CycloneDX SBOM with each release, running cargo-deny in CI to check advisories, licenses, and allowed registries, and signing builds with SHA-256 checksums. The project's Open Source nature allows independent verification of the embedded code.

How this translates into use

Concretely, here's what a user observes. The first time a connection is opened after a restart: the operating system asks for keychain authentication to decrypt the password. Once the session is unlocked, access is immediate as long as the OS considers the user active.

A connection labeled Production shows red borders in the sidebar, in the query tab, in the data grid. Running DROP TABLE on this connection produces a clear error even before the query reaches the engine. Running DELETE FROM orders without a WHERE opens a confirmation dialog that reminds you of the environment and requires explicit confirmation.

On the observability side, the audit screen displays already-redacted query text, with a fingerprint that lets you group variants. The audit export (JSON, JSONL, or CSV) reads the full log from disk, not just the memory cache, which makes possible an after-the-fact analysis consistent with the configured retention.

Summary

QoreDB's security model is calibrated for its context: a single user, on their machine, with their own databases. The first-order defenses target the two most likely risks: credential theft by local malware and accidental destruction of data. The second-order defenses cover local persistence (redaction, redacted audit, CSP isolation) and the supply chain (SBOM, signatures, monitored dependencies).

The goal is not to replicate the model of a multi-tenant service. It's to offer protection consistent with the desktop context, without hiding either the nature or the scope of each mechanism.

Newsletter

Stay updated on new releases

Subscribe to get product releases, new drivers notifications, and technical tutorials.

🎁 Bonus: Get our free SQL Performance Cheat Sheet — 9 pages, PostgreSQL / MySQL / SQLite (PDF)!
Share
QoreDB's Security Model: Threats and Countermeasures - Blog - QoreDB