Projekt

Allgemein

Profil

Aktionen

PG Authentication Delegation

Option 1

  • --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.
    
    
  • 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:
    psql -d some_database -U webgui
    (enter s3cr3t as password)
    
    set role neil;
    
    
  • webgui does not need superuser permission for this.
  • die Variante beinhaltet enorme Sicherheitslücke:
    • RESET ROLE;
      SET ROLE admin;
      
    • 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

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
  • 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;
    
  • 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

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 ändert das PW der Login-Rolle auf das neue PW
    • Neues PW wird im CM gesichert
  • Niemand auser dem WebService (oder implizit alle welche das Passwort des Windows-Accounts kennen und wissen wonach sie schauen müssen und wie es funktioniert) kann sich damit mit der Login-Rolle in den PG einlogen

Von [E] Rocco Kreutz vor 4 Monaten aktualisiert · 5 Revisionen