Projekt

Allgemein

Profil

PG Authentication Delegation » Historie » Revision 4

Revision 3 ([E] Rocco Kreutz, 23.10.2024 12:42) → Revision 4/5 ([E] Rocco Kreutz, 23.10.2024 12:57)

h1. PG Authentication Delegation 

 h2. Option 1 

 * <pre><code class="sql"> 
 --create a user that you want to use the database as: 

 create role neil; 

 --create the user for the web server to connect as: 

 create role webgui noinherit login password 's3cr3t'; 

 --let webgui set role to neil: 

 grant neil to webgui; --this looks backwards but is correct. 

 </code></pre> 
 * webgui is now in the neil group, so webgui can call set role neil . However, webgui did not inherit neil's permissions. 
 * Later, login as webgui: 
 <pre><code class="sql"> 
 psql -d some_database -U webgui 
 (enter s3cr3t as password) 

 set role neil; 

 </code></pre> 
 * webgui does not need superuser permission for this. 
 * *die Variante beinhaltet enorme Sicherheitslücke:* 
 ** <pre><code class="sql"> 
 RESET ROLE; 
 SET ROLE admin; 
 </code></pre> 
 ** da hierfür alle Rollen welche sich einlogen können sollen Mitglied der Login-Rolle sind (webgui), kann hiermit zu allen anderen Rollen gewechselt werden 

 h2. Option 2 

 * Funktionen welche als @SECURITY DEFINER@ deklariert sind, dürfen kein @SET ROLE@    (Änderungen des "current_user") und auch kein @SET AUTHORIZATION@ (Änderung des "session_user") aufrufen 
 * <pre><code class="sql"> 
 CREATE OR REPLACE FUNCTION TSystem.grantrole(role_name text) RETURNS void AS $$ 
 DECLARE 
   _SQL varchar; 
 BEGIN 
   _SQL = format('GRANT %I TO %I;', role_name, session_user); 
   EXECUTE _SQL; 
 END; 
 $$ LANGUAGE plpgsql SECURITY DEFINER; 

 CREATE OR REPLACE FUNCTION TSystem.revokerole(role_name text) RETURNS void AS $$ 
 DECLARE 
   _SQL varchar; 
 BEGIN 
   _SQL = format('REVOKE %I FROM %I;', role_name, session_user); 
   EXECUTE _SQL; 
 END; 
 $$ LANGUAGE plpgsql SECURITY DEFINER; 

 CREATE OR REPLACE FUNCTION TSystem.switchrole(role_name text) RETURNS void AS $$ 
 DECLARE 
   _SQL varchar; 
 BEGIN 
   -- check for permission here -> IF THEN   
   PERFORM TSystem.grantrole(role_name); 
   _SQL = format('SET ROLE %I;', role_name); 
   EXECUTE _SQL; 
   PERFORM TSystem.revokerole(role_name); 	
 END; 
 $$ LANGUAGE plpgsql; 
 </code></pre> 
 * Niemand ausser der webui Rolle bekommt jetzt das Recht diese Funktionen auszuführen 
 * Für alle Tabellen mit alternativen Authentifizierungs-Feldern (llv.ll_rfid) wird RLS aktiviert @ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;@ 
 ** Lesen: SUPERUSER ODER session_user (nicht current_user !!!) 
 ** Schreiben: session_user 
 ** Keine Werte speichern, stattdessen SALT's und Hashes speichern 
 ** die hier nicht aufgeführte Funktion zum überprüfen der alternativen Authentifizierung (NFC/RFID oder was auch immer in Zukunft nötig wird) wird mit @SECURITY DEFINER@ definiert und alleinig @EXECUTE@ für alle gesetzt 
 * Damit ist alleinig für den Moment der Ausführung von TSystem.switchrole eine Rolle Mitglied der Login-Rolle 
 ** Um dies dann als Sicherheitslücke ausnutzen zu können, müsste jemand in dem winzigen Moment in dem ein admin sich mittels der Login-Rolle einlogged und Mitglied der Login-Rolle ist; @RESET ROLE; SET ROLE admin;@ ausführen 

 h3. Absicherung der Login-Rolle 

 * Keine Rechte für die Rolle ausser dem Ausführen der obigen Funktionen 
 * Das Passwort wird mittels Credential-Manager verwaltet (Damit kann nur der Windows-Account dieses lesen, unter welchem der WebServer läuft) 
 * Das Passwort der Login-Rolle wird initial im PG gesetzt von einem "Prodat-Admin" 
 * Dannach logged sich der "Prodat-Admin" im WebServer ein und übergibt die Kontrolle darüber an den WebServer 
 ** WebServer benutzt initiales PW um sich in PG einzuloggen 
 ** WebServer erzeugt neues PW und änder das PW der Login-Rolle auf das neue PW 
 ** Neues PW wird im CM gesichert