stolon icon indicating copy to clipboard operation
stolon copied to clipboard

Hide root & replication users password logs from Postgres

Open keierk01 opened this issue 5 years ago • 4 comments

What would you like to be added: Hide root and replication roles passwords from Postgres logs in startup phase

Why is this needed: Even logs are usually treated as confidential content it's not good idea to have any passwords visible there. Currently Stolon use CREATE ROLE or ALTER ROLE commands to set password for Postgres roles. This generates Postgres log entry as cleartext password included. See example below.

2020-07-10 15:16:53 UTC:[local]:postgres@postgres:[67]:LOG:  statement: alter role postgres with password 'PostgresRootPassword';
2020-07-10T15:16:53.315Z        INFO    postgresql/postgresql.go:538    superuser password set
2020-07-10T15:16:53.315Z        INFO    postgresql/postgresql.go:541    creating replication role
2020-07-10 15:16:53 UTC:[local]:postgres@postgres:[68]:LOG:  statement: create role "stolon_repluser" with login replication encrypted password 'StolonReplUserPassword';
2020-07-10T15:16:53.319Z        INFO    postgresql/postgresql.go:551    replication role created        {"role": "stolon_repluser"}

Possible solution would be to hide Postgres logs temporary when altering or creating Postgres role. See example from stackexchange

BEGIN;
SET LOCAL log_statement = 'none';
ALTER USER ... SET PASSWORD ...;
COMMIT;

Something like below with Go when set password to Postgres role.

func setPassword(ctx context.Context, connParams ConnParams, username, password string) error {
	db, err := sql.Open("postgres", connParams.ConnString())
	if err != nil {
		return err
	}
	defer db.Close()

	tx, err := db.Begin()
	if err != nil {
		return err
	}

	// Disable logs temporary to prevent password expose in logs
	query := fmt.Sprintf("SET LOCAL log_statement = %s", pg.QuoteLiteral("none"))
	if _, err := tx.Exec(query); err != nil {
		err := tx.Rollback()
		return err
	}

	query = fmt.Sprintf("ALTER ROLE %s WITH PASSWORD %s", pg.QuoteIdentifier(username), pg.QuoteLiteral(password))
	if _, err := tx.Exec(query); err != nil {
		err := tx.Rollback()
		return err
	}
	tx.Commit()

	return err
}

keierk01 avatar Jul 22 '20 13:07 keierk01

@keierk01 You quite probably set log_statement to all (postgres default is none: https://www.postgresql.org/docs/9.4/runtime-config-logging.html#GUC-LOG-STATEMENT). So I don't think we should do something.

sgotti avatar Jul 22 '20 13:07 sgotti

Yes, that's true. We are setting log_statement to ddl and therefore ALTER ROLE is visible in logs. However, that password visibility could be solved by my proposal even having log_statement as ddl. I have tested that in my other component in stolon cluster with ddl log_statement.

keierk01 avatar Jul 22 '20 14:07 keierk01

@keierk01 Can you please open a Pull Request?

sgotti avatar Jul 22 '20 15:07 sgotti

@sgotti I don't have time to do that now, but I can do that later at Aug-Sep timeframe. If you have time, please go ahead and make the changes but as I said, I can do that change later if needed.

keierk01 avatar Jul 23 '20 07:07 keierk01