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.