Skip to main content

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.

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.