Security
PG Dashboard builds dynamic SQL, so security is a core part of the package.
SQL Injection Protection
The backend does not trust table, view, function, or column names coming from the frontend.
Before execution, names are validated against PostgreSQL metadata. Values are sent through native pg placeholders:
WHERE "name" ILIKE $1
This means user-provided values are not concatenated directly into SQL strings.
Identifier Whitelisting
Dynamic identifiers are validated against database metadata before use:
- relation names are checked against known tables, views, and materialized views;
- column names are checked against the selected relation;
- function names are checked against known functions;
- CRUD columns are restricted to writable columns.
Mutation Features Are Opt-In
Potentially dangerous features are disabled by default:
pgDashboard({
enableCrud: false,
enableFunctions: false,
});
Enable them only when the dashboard is protected and the user is expected to mutate data or execute functions.
Recommended PostgreSQL User
Use a dedicated PostgreSQL user with the smallest useful permissions.
For read-only dashboards, prefer a user with only SELECT permissions:
GRANT USAGE ON SCHEMA public TO dashboard_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO dashboard_user;
For CRUD, grant only what is necessary:
GRANT SELECT, INSERT, UPDATE, DELETE ON target_table TO dashboard_user;
Authentication
PG Dashboard does not ship authentication. Protect the mounted route in your Express app:
app.use("/admin/db", requireAdminUser, pgDashboard({ connectionString }));
Never mount the dashboard on a public route without access control.