You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Driver: PostgreSQL
Category: Security
Severity: MEDIUM
Problem:
It is currently not possible to use the postgres storage driver without elevated user permissions that allow the user to arbitrarily create tables. This is even true if you already have a table that matches the desired schema. The behaviour is different than valkey, redis, and a number of other drivers where table/namespace create permissions are considered elevated permissions that a webserver should not posses for normal operations.
Always runs init query when initializing the storage:
Root Cause:
The issue seems to mainly arise because of the way that the PostgreSQL query engine(QE) is built. The QE seems to preflight the query to ensure the user has the permissions to perform all of the actions in the query, even if a logic branch may never be taken (i.e. QE will verify user has CREATE permission even though query has the IF NOT EXISTS predicate and table already exists). This behaviour is expected and pretty good as it minimizes the need for the QE to do permission checks during row-locking/table-locking operations.
Potential Fixes:
Bare minimum fix:
Run two separate queries, (1) first check if table exists, (2) if table does not exists, then create table
Slightly better fix:
Add Config flag that disables all Create/Drop operations, and panics/raises error if table does not exist, schema does not match, or reset via DROP is set to true
Tangential fixes:
Reset function should TRUNCATE instead of DROP to accomplish the goal of:
// Reset clears any existing keys in existing Table
//
// Optional. Default is false
Resetbool
How to Reproduce
Steps to reproduce the behaviour:
Create a user in postgres that has full table and usage permissions, but no create permissions:
CREATEDATABASEfiber_store;
CREATE ROLE fiber_users;
GRANT CONNECT ON DATABASE fiber_user TO fiber_users;
GRANT USAGE ON SCHEMA public TO fiber_users;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO fiber_users;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO fiber_users;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO fiber_users;
CREATEUSERfiber_users WITH PASSWORD 'password';
GRANT fiber_users TO fiber_user;
Connect to database using the admin user in psql or SQL IDE
Create the table expected by Storage
CREATETABLEIF NOT EXISTS sessions (
k VARCHAR(64) PRIMARY KEYNOT NULL DEFAULT '',
v BYTEANOT NULL,
e BIGINTNOT NULL DEFAULT '0'
);
CREATEINDEXIF NOT EXISTS e ON sessions (e);
Create a new barebones Go program
Create a github.com/gofiber/storage/postgres/v3 storage connection using the newly created fiber_user
go run program
Program will panic with the following error:panic: ERROR: permission denied for schema public (SQLSTATE 42501)
Change user to admin user (usually postgres)
go run updated program
Program will proceed normally.
Check db schema, table will be unaltered
Expected Behavior
If table already exists, matches desired schema and Config{ Reset: false }, store should connect successfully and continue normally.
Bug Description
Driver: PostgreSQL
Category: Security
Severity: MEDIUM
Problem:
It is currently not possible to use the
postgres
storage driver without elevated user permissions that allow the user to arbitrarily create tables. This is even true if you already have a table that matches the desired schema. The behaviour is different thanvalkey
,redis
, and a number of other drivers where table/namespace create permissions are considered elevated permissions that a webserver should not posses for normal operations.Always runs init query when initializing the storage:
storage/postgres/postgres.go
Lines 73 to 78 in fb997fd
init query will fail if user does not have
CREATE ON SCHEMA
permission, even if table already exists:storage/postgres/postgres.go
Lines 32 to 39 in fb997fd
Root Cause:
The issue seems to mainly arise because of the way that the PostgreSQL query engine(QE) is built. The QE seems to preflight the query to ensure the user has the permissions to perform all of the actions in the query, even if a logic branch may never be taken (i.e. QE will verify user has
CREATE
permission even though query has theIF NOT EXISTS
predicate and table already exists). This behaviour is expected and pretty good as it minimizes the need for the QE to do permission checks during row-locking/table-locking operations.Potential Fixes:
Bare minimum fix:
Run two separate queries, (1) first check if table exists, (2) if table does not exists, then create table
Slightly better fix:
Add Config flag that disables all Create/Drop operations, and panics/raises error if table does not exist, schema does not match, or reset via
DROP
is set totrue
Tangential fixes:
Reset function should
TRUNCATE
instead ofDROP
to accomplish the goal of:storage/postgres/config.go
Lines 59 to 62 in fb997fd
How to Reproduce
Steps to reproduce the behaviour:
psql
or SQL IDEStorage
github.com/gofiber/storage/postgres/v3
storage connection using the newly createdfiber_user
go run
programpanic: ERROR: permission denied for schema public (SQLSTATE 42501)
postgres
)go run
updated programExpected Behavior
If table already exists, matches desired schema and
Config{ Reset: false }
, store should connect successfully and continue normally.Storage package Version
v3.0.1
Code Snippet (optional)
Checklist:
The text was updated successfully, but these errors were encountered: