Zunächst einige Hintergrundinformationen.
Das LedgerSMB-Projekt ist eine Open-Source-Finanzbuchhaltungssoftware, die auf PostgreSQL ausgeführt wird. Wir implementieren eine sehr große Menge an Geschäftslogik in benutzerdefinierten Funktionen, die als wichtigstes Mapping-Tool zwischen Programmobjektmethoden und Datenbankverhalten fungieren. Gegenwärtig verwenden wir Datenbankbenutzer als Authentifizierungsbenutzer, teils nach Wahl (dies ermöglicht eine zentralisierte Sicherheitslogik, damit andere Tools geschrieben und die den Benutzern erteilten Berechtigungen wiederverwendet werden können), teils nach Bedarf (nachdem wir uns von SQL-Ledger getrennt haben) Es gab nicht viele Möglichkeiten, die Sicherheit auf dieser Codebasis nachzurüsten.
Dies verschafft uns Zugang zu einer angemessenen Anzahl von Einzelanmeldungsoptionen, auf die PostgreSQL Zugriff hat, von LDAP bis Kerberos 5. Wir können sogar PAM verwenden, wenn es um Passwörter geht. Außerdem können wir Berechtigungen bei der Integration in andere Anwendungen oder beim Zulassen anderer Clientschnittstellen wiederverwenden. Für eine Finanzbuchhaltungsanwendung scheint dies ein Nettogewinn zu sein.
Es gibt offensichtliche Kosten. Für die Webanwendung sind wir stark auf die Arten von http-Authentifizierung beschränkt, die unterstützt werden können. DIGEST zum Beispiel ist komplett aus. BASIC funktioniert, und wir könnten KRB5 problemlos implementieren (ich plane, dies zu unterstützen und für 1.4 sofort einsatzbereit zu machen). Sehr starke Authentifizierungsmaßnahmen können auf diese Weise nicht direkt ordnungsgemäß verwaltet werden, obwohl wir sie möglicherweise bei Bedarf einbinden könnten (z. B. clientseitiges BASIC + -Zertifikat mit einer cn, die dem Benutzernamen entspricht, und einer bestimmten Stammzertifizierungsstelle).
Gleichzeitig sind wir auf eine Menge Kritik gestoßen, vor allem von Seiten der Entwickler und gelegentlich von dba's, die mir sagen, dass die Anwendung die Sicherheitsbarriere sein sollte, nicht die Datenbank. Ich bin immer noch der Ansicht, dass ein kleinerer Sicherheitsbereich im Allgemeinen besser ist, dass die Wiederverwendung von Geschäftslogik und Sicherheitslogik zusammengehört und dass die Wiederverwendung von Geschäftslogik ohne die Wiederverwendung von Sicherheitslogik auf derselben Ebene für mich gefährlich ist des Programms.
Vermisse ich hier irgendwelche großen Kompromisse? Gibt es Fallstricke, die ich nicht in Betracht ziehe?
quelle
Antworten:
Ich denke, Sie verschmelzen Authentifizierung und Autorisierung .
Ich stimme voll und ganz zu, dass es sinnvoll ist, das Sicherheitsmodell in der Datenbank beizubehalten, zumal LedgerSMB für den Zugriff mehrerer Clients konzipiert wurde. Sofern Sie nicht vorhaben, eine Middleware-Schicht in drei Ebenen einzurichten, ist es absolut sinnvoll, Benutzer als Datenbankrollen zu verwenden, insbesondere für eine Buchhaltungs-App.
Dies bedeutet nicht, dass Sie Benutzer mit einer von PostgreSQL unterstützten Authentifizierungsmethode gegenüber der Datenbank authentifizieren müssen. Ihre Datenbankbenutzer, Rollen und Berechtigungen können nur dann für die Autorisierung verwendet werden , wenn Sie dies möchten.
So funktioniert es beispielsweise für eine Web-Benutzeroberfläche:
jane
Stellt eine Verbindung zum Web-UI-Server her und authentifiziert sich mit einer beliebigen Methode, z. B. HTTPS X.509-Client-Zertifikat-Handshake und DIGEST-Authentifizierung. Der Server hat jetzt eine Verbindung von einem Benutzer, den er wirklich akzeptiertjane
.Der Server verbindet sich mit PostgreSQL mit einem festen Benutzernamen / Passwort (oder Kerberos oder was auch immer Sie möchten) und authentifiziert sich gegenüber dem Datenbankserver als Benutzer
webui
. Der db server vertraut daraufwebui
, seine Benutzer zu authentifizieren, so dasswebui
ihm die entsprechendenGRANT
s zugewiesen wurden (siehe unten).Bei dieser Verbindung
SET ROLE jane;
übernimmt der Server die Berechtigungsstufe des Benutzersjane
. Bis der eineRESET ROLE;
oder andere ausgeführtSET ROLE
wird, arbeitet die Verbindung mit den gleichen Zugriffsrechten wiejane
und wirdSELECT current_user()
usw. gemeldetjane
.Der Server behält die Zuordnung zwischen der Datenbankverbindung, auf der er sich befindet
SET ROLE
,jane
und der Websitzung für den Benutzer beijane
und lässt nicht zu, dass diese PostgreSQL-Verbindung von anderen Verbindungen mit anderen Benutzern verwendet wird, ohne dassSET ROLE
dazwischen eine neue Verbindung besteht .Sie authentifizieren sich jetzt außerhalb des Servers, behalten jedoch die Autorisierung auf dem Server bei. Pg muss wissen, welche Benutzer vorhanden sind, benötigt jedoch keine Kennwörter oder Authentifizierungsmethoden.
Sehen:
SET SESSION AUTHORIZATION
SET ROLE
GRANT
Einzelheiten
Der Webui-Server steuert die Ausführung der Abfragen und lässt
jane
Raw-SQL nicht laufen (hoffe ich!),jane
Kann also nichtRESET ROLE; SET ROLE special_admin_user;
über die Web-Benutzeroberfläche ausgeführt werden. Zusätzliche Sicherheit würde ich eine Erklärung Filter auf den Server hinzufügen , die abgelehntSET ROLE
undRESET ROLE
es sei denn , die Verbindung war in oder einen Pool von nicht zugeordneten Verbindungen eingeben.Es steht Ihnen weiterhin frei, die direkte Authentifizierung gegenüber PG in anderen Clients zu verwenden. Sie können frei mischen und zusammenpassen. Sie müssen
GRANT
demwebui
Benutzer lediglich die Rechte fürSET ROLE
Benutzer erteilen, die sich über das Web anmelden und diesen Benutzern dann dieCONNECT
gewünschten normalen Rechte, Kennwörter usw. erteilen können . Wenn Sie sie nur für das Web verwenden möchten, geben SieREVOKE
ihreCONNECT
Rechte für die Datenbank (und vonpublic
) an.Um eine solche Authentifizierung / Autorisierung möglichst einfach aufzuteilen, habe ich eine besondere Rolle
assume_any_user
, die ichGRANT
jedem neu angelegten Benutzer zugedacht habe. Ich werde dannGRANT assume_any_user
zu dem echten Benutzernamen, der von Dingen wie einem vertrauenswürdigen Web-Front-End verwendet wird, und gebe ihnen das Recht, jeder Benutzer zu werden, den sie mögen.Es ist wichtig,
assume_any_user
eineNOINHERIT
Rolle zu spielen, damit derwebui
Benutzer oder was auch immer selbst keine Rechte hat und nur dann auf die Datenbank einwirken kann, wenn es sichSET ROLE
um einen echten Benutzer handelt. Unter keinen Umständen solltewebui
ein Superuser oder DB-Besitzer sein .Wenn Sie ein Verbindungspooling durchführen, können Sie
SET LOCAL ROLE
die Rolle nur innerhalb einer Transaktion festlegen, sodass Sie nachCOMMIT
oder Verbindungen zum Pool zurückgeben könnenROLLBACK
. Beachten Sie, dass diesRESET ROLE
immer noch funktioniert. Es ist also immer noch nicht sicher, dass der Client das von ihm gewünschte SQL ausführt.SET SESSION AUTHORIZATION
ist die verwandte, aber stärkere Version dieses Befehls. Es ist keine Rollenmitgliedschaft erforderlich, aber es handelt sich um einen Superuser-Befehl. Sie möchten nicht, dass sich Ihre Webbenutzeroberfläche als Superuser verbindet. Es kann mit rückgängig gemacht werdenRESET SESSION AUTHORIZATION
,SET SESSION AUTHORIZATION DEFAULT
oderSET SESSION AUTHORIZATION theusername
Superuser - Rechte wieder zu erlangen , so dass es entweder kein Privileg-dropping Sicherheitsbarriere ist.Ein Befehl, der funktioniert hat,
SET SESSION AUTHORIZATION
aber irreversibel ist und funktioniert, wenn Sie ein Rollenmitglied, aber kein Superuser sind, wäre großartig. Zu diesem Zeitpunkt gibt es noch keine, aber Sie können Authentifizierung und Autorisierung recht gut trennen, wenn Sie vorsichtig sind.Beispiel und Erklärung
Jetzt verbinden als
webui
. Beachten Sie, dass Sie nicht alles tun , umtest_table
aber Sie könnenSET ROLE
aufjane
und dann können Sie zugreifentest_table
:Beachten Sie, dass
webui
DoseSET ROLE
zujim
, auch wenn schonSET ROLE
d zujane
und obwohljane
wird nichtGRANT
das Recht ed die Rolle zu übernehmenjim
.SET ROLE
Legt Ihre effektive Benutzer-ID fest, jedoch nicht, dass SieSET ROLE
andere Rollen zuweisen können. Dies ist eine Eigenschaft der Rolle, mit der Sie verbunden sind, und nicht Ihre aktuelle effektive Rolle. Folglich müssen Sie den Zugriff auf die BefehleSET ROLE
und sorgfältig kontrollierenRESET ROLE
. Es gibt, AFAIK, keine MöglichkeitSET ROLE
für eine dauerhafte Verbindung, wirklich zum Zielbenutzer zu werden, obwohl es sicherlich schön wäre, eine zu haben.Vergleichen Sie:
zu:
Dies bedeutet, dass
SET ROLE
die Anmeldung nicht mit einer bestimmten Rolle identisch ist, was Sie berücksichtigen müssen.webui
kann nichtSET ROLE
,dbowner
da es nicht soGRANT
richtig bearbeitet wurde:Daher ist es für sich genommen ziemlich machtlos. Es kann nur die Rechte anderer Benutzer übernehmen und nur, wenn für diese Benutzer der Webzugriff aktiviert ist.
quelle
pgbouncer
für einige Details funktioniert.DISCARD ALL
ist eine andere Möglichkeit, um Rechte auf den Standard zurückzusetzen. Ich wünschte wirklich, Pg hätte eineSET ROLE NORESET
oder ähnliche ...