Najpierw jakieś tło.
Projekt LedgerSMB to projekt oprogramowania księgowego o otwartym kodzie źródłowym, który działa na PostgreSQL. Implementujemy bardzo dużą logikę biznesową w funkcjach zdefiniowanych przez użytkownika, które działają jako główne narzędzie mapowania między metodami obiektów programu a zachowaniem bazy danych. Obecnie używamy użytkowników bazy danych jako użytkowników uwierzytelniających, częściowo z wyboru (pozwala to na scentralizowaną logikę bezpieczeństwa, dzięki czemu można pisać inne narzędzia i ponownie udzielać użytkownikom uprawnień), a częściowo z konieczności (po przejściu na SQL-Ledger, tam nie było wielu opcji modernizacji zabezpieczeń w tej bazie kodów).
To daje nam dostęp do rozsądnej liczby opcji pojedynczego logowania, do których ma dostęp PostgreSQL, od LDAP do Kerberos 5. Możemy nawet używać PAM, jeśli chodzi o hasła. Pozwala nam również ponownie wykorzystywać uprawnienia podczas integracji z innymi aplikacjami lub zezwalając na inne interfejsy klienta. W przypadku rachunkowości finansowej wydaje się to wygraną netto.
Wiąże się to z oczywistymi kosztami. W przypadku aplikacji internetowej jesteśmy bardzo ograniczeni do typów uwierzytelniania HTTP, które mogą być obsługiwane. Na przykład DIGEST jest całkowicie niedostępny. BASIC działa, a my moglibyśmy zaimplementować KRB5 dość łatwo (planuję mieć to obsługiwane i działać od razu z wersji 1.4). Bardzo silnymi środkami uwierzytelniania nie można właściwie zarządzać bezpośrednio na tym, chociaż prawdopodobnie moglibyśmy je w razie potrzeby pomijać (na przykład certyfikat SSL po stronie klienta BASIC + z cn pasującym do nazwy użytkownika i określonego katalogu głównego).
W tym samym czasie spotkałem się z dużą krytyką głównie ze strony tłumaczy programistów, a sporadycznie od dba, którzy twierdzą, że aplikacja powinna stanowić barierę bezpieczeństwa, a nie bazę danych. Nadal uważam, że mniejszy obwód bezpieczeństwa jest ogólnie lepszy, że ponowne użycie logiki biznesowej i logiki bezpieczeństwa idzie w parze i że wydaje mi się niebezpieczne ponowne użycie logiki biznesowej bez ponownego użycia logiki bezpieczeństwa na tym samym poziomie programu.
Czy brakuje mi tutaj poważnych kompromisów? Czy są jakieś braki, których nie rozważam?
źródło
Odpowiedzi:
Myślę, że łączysz uwierzytelnianie i autoryzację .
Całkowicie się zgadzam, że zachowanie modelu bezpieczeństwa w DB jest mądre, zwłaszcza, że LedgerSMB został zaprojektowany z myślą o dostępie wielu klientów. Jeśli nie planujesz przejścia 3-warstwowego z warstwą oprogramowania pośredniego, będzie to idealne rozwiązanie sens mieć użytkownikom jak role baz danych, zwłaszcza na coś aplikacji księgowych.
Ten sposób nie oznacza, że musisz uwierzytelniać użytkowników przeciwko bazy danych przy użyciu metody uwierzytelniania PostgreSQL obsługiwane. Użytkownicy bazy danych, role i granty mogą być używane do autoryzacji tylko, jeśli chcesz.
Oto jak to działa na przykład w interfejsie internetowym:
jane
łączy się z serwerem interfejsu WWW i uwierzytelnia się za pomocą dowolnej metody, powiedzmy handshake certyfikatu klienta HTTPS X.509 i autoryzację DIGEST. Serwer ma teraz połączenie od użytkownika, który akceptujejane
.Serwer łączy się z PostgreSQL przy użyciu stałej nazwy użytkownika / hasła (lub Kerberos lub cokolwiek innego), uwierzytelniając się na serwerze db jako użytkownik
webui
. Serwer db ufawebui
uwierzytelnianiu swoich użytkowników, dlategowebui
otrzymał odpowiednieGRANT
s (patrz poniżej).W przypadku tego połączenia serwer
SET ROLE jane;
przyjmuje poziom autoryzacji użytkownikajane
. DopókiRESET ROLE;
lub innySET ROLE
jest prowadzony, połączenie działa z tych samych praw dostępu, jakjane
iSELECT current_user()
etc zgłosijane
.Serwer utrzymuje powiązanie między połączeniem bazy danych, z którym musi
SET ROLE
się połączyć,jane
a sesją internetową dla użytkownikajane
, nie pozwalając, aby to połączenie PostgreSQL było używane przez inne połączenia z innymi użytkownikami bez nowejSET ROLE
przerwy między nimi.Teraz uwierzytelniasz się poza serwerem, ale zachowujesz autoryzację na serwerze. Pg musi wiedzieć, którzy użytkownicy istnieją, ale nie potrzebuje dla nich haseł ani metod uwierzytelniania.
Widzieć:
SET SESSION AUTHORIZATION
SET ROLE
GRANT
Detale
Serwer webui kontroluje uruchamianie zapytań i nie pozwoli na
jane
uruchomienie surowego SQL (mam nadzieję!), Więcjane
nie możeRESET ROLE; SET ROLE special_admin_user;
za pośrednictwem interfejsu WWW. Dla większego bezpieczeństwa dodam filtr instrukcji do serwera, który odrzuciłSET ROLE
iRESET ROLE
chyba, że połączenie było w puli nieprzypisanych połączeń lub nie wchodziło do niej.Nadal możesz swobodnie korzystać z bezpośredniego uwierzytelniania Pg na innych klientach; możesz dowolnie mieszać i dopasowywać. Po prostu trzeba
GRANT
nawebui
użytkownika prawa doSET ROLE
użytkowników, którzy mogą logować się za pośrednictwem Internetu, a następnie dać tym użytkownikom żadnych normalnychCONNECT
praw, haseł, itp chcesz. Jeśli chcesz, aby były dostępne tylko w Internecie,REVOKE
ichCONNECT
prawa do bazy danych (i odpublic
).Aby ułatwić podział uwierzytelnienia / autoryzacji, mam szczególną rolę
assume_any_user
, do którejGRANT
każdy nowo utworzony użytkownik. Ja wtedyGRANT assume_any_user
przechodzę do prawdziwej nazwy użytkownika używanej przez takie rzeczy, jak zaufany interfejs internetowy, dając im prawa do zostania dowolnym użytkownikiem, którego lubią.Ważne jest, aby
assume_any_user
naNOINHERIT
rolę, więcwebui
użytkownik lub cokolwiek ma privilges przez jego własny i może działać tylko w bazie danych po toSET ROLE
do prawdziwego użytkownika. Pod żadnym pozorem nie powinienwebui
być superużytkownikiem ani właścicielem bazy danych .Jeśli korzystasz z puli połączeń, możesz użyć,
SET LOCAL ROLE
aby ustawić rolę tylko w ramach transakcji, abyś mógł zwracać połączenia do puli poCOMMIT
lubROLLBACK
. Strzeż się, żeRESET ROLE
nadal działa, więc nadal nie jest bezpieczne, aby klient mógł uruchamiać dowolny SQL, jaki chcą.SET SESSION AUTHORIZATION
jest powiązaną, ale silniejszą wersją tego polecenia. Nie wymaga przynależności do roli, ale jest to tylko polecenie administratora. Nie chcesz, aby interfejs użytkownika sieci Web był łączony jako administrator. To może być odwróconeRESET SESSION AUTHORIZATION
,SET SESSION AUTHORIZATION DEFAULT
lubSET SESSION AUTHORIZATION theusername
odzyskać praw superużytkownika, więc nie jest to bariera bezpieczeństwa przywilej opada albo.Polecenie, które działało jak
SET SESSION AUTHORIZATION
ale było nieodwracalne i działałoby, gdybyś był członkiem roli, ale nie superużytkownikiem, byłoby świetne. W tym momencie nie ma jednego, ale nadal możesz całkiem dobrze rozdzielić uwierzytelnianie i autoryzację, jeśli jesteś ostrożny.Przykład i wyjaśnienie
Teraz połącz jako
webui
. Należy pamiętać, że nie można nic zrobić,test_table
ale możeSET ROLE
sięjane
i wtedy można uzyskać dostęptest_table
:Należy pamiętać, że
webui
puszkaSET ROLE
dojim
, nawet gdy jużSET ROLE
dni dojane
i chociażjane
nie zostałGRANT
ed prawo przyjąć rolęjim
.SET ROLE
ustawia efektywny identyfikator użytkownika, ale nie usuwa twojej zdolności doSET ROLE
pełnienia innych ról, jest to właściwość roli, którą podłączyłeś, a nie twojej obecnej skutecznej roli. W związku z tym musisz dokładnie kontrolować dostęp do poleceńSET ROLE
iRESET ROLE
. Nie ma, AFAIK, żadnego sposobu na stałeSET ROLE
połączenie, naprawdę stając się docelowym użytkownikiem, choć na pewno byłoby miło mieć.Porównać:
do:
Oznacza to, że
SET ROLE
nie jest to dokładnie to samo, co logowanie się w ramach określonej roli, o czym należy pamiętać.webui
nie mogę tegoSET ROLE
zrobić,dbowner
ponieważ nie zostałoGRANT
to odpowiednio poprawione:więc sam w sobie jest dość bezsilny, może przejąć prawa innych użytkowników i tylko wtedy, gdy ci użytkownicy mają włączony dostęp do sieci.
źródło
pgbouncer
działa dla niektórych szczegółów.DISCARD ALL
to kolejny sposób na przywrócenie praw do wartości domyślnych. Naprawdę chciałbym, żeby Pg miał cośSET ROLE NORESET
podobnego ...