6

Szukam dobrego wzorca do implementacji kontroli bezpieczeństwa na poziomie wiersza (za pośrednictwem np. Serwera proxy, usługi sieci pośredniej lub procedur składowanych) odpowiednich do użytku w środowisku klienta-> bazy danych. Kontroluję zarówno klienta, jak i bazę danych. Niektóre wymagania:Zabezpieczenia na poziomie wiersza w scenariuszu z klientem bazy danych

  • Zakazanie użytkownikom wyświetlanie wierszy w zapytaniu wynika, że ​​nie ma uprawnień, aby zobaczyć
  • dzięki czemu użytkownicy mogą wstawiać i aktualizować swoje wiersze do tabeli, która daje im pozwolenie, aby zobaczyć je
  • (wymóg miękki) umożliwiający użytkownikom udzielanie innym dostępu do odczytu lub zapisu wierszy
  • Rozwiązanie typu open source lub tanie, działające pod kontrolą systemu Linux. Jak rozumiem, żadna bezpłatna baza danych nie implementuje zabezpieczeń na poziomie wiersza jako takich. Oracle obsługuje to, ale jest zbyt $$$$. Postgres might be implementing this in 9.4, ale pierwotnie był przeznaczony dla 9.3 i poślizgnął się i jest dyskusja na temat ML, że może on się poślizgnąć ponownie. Wstępnie myślę o używaniu Postgreas tylko dlatego, że wydają się być najdalej od tej funkcji.

Niektórzy (niezbyt dobrze) pomysły miałem:

  • Używanie widoków PostgreSQL bariery bezpieczeństwa i odmówić użytkownikowi dostępu do tabeli podstawowej. Niestety istnieje no good way to insert a row into a security barrier view, więc niektóre uprzywilejowane proxy/usługa sieciowa musiałaby obsługiwać instrukcje wstawiania. Wydaje się, że trudno to naprawić.
  • Użyj zwykłych widoków i odmów użytkownikom dostępu do tabeli podstawowej. To pozwala na insert, ale musiałbym zamknąć uprawnienia dość mocno (na przykład brak tworzenia funkcji) i there seem to be a lot of gotchas (like divide by zero) that leak information.
  • Zdefiniuj niektóre podzestawy SQL i utwórz serwer proxy, który jest jedynym punktem komunikacji z bazą danych. Serwer proxy analizuje zapytanie SQL i przepisuje je w celu wymuszenia wymagań bezpieczeństwa. Wydaje się, że trudno to zrobić w ogóle, ale być może uda mi się uciec z bardzo małym podzbiorem SQL, dopóki postgres nie zastosuje prawdziwego zabezpieczenia na poziomie wiersza.
  • Po prostu różne tabele dla różnych użytkowników (lub nawet różnych DB). Jednak nie jestem pewien, jak dobrze to skaluje do wielu użytkowników. Wydaje się również, że nie spełnia to wymagań miękkich.
  • Znajdź jakiś komercyjny, ale rozsądne DB-kosztowej, że faktycznie obsługuje tej
  • Zastosowanie Veil ale nie wydaje się być utrzymane, a to ma większość ograniczeń innych rozwiązań

Zrobiłem dużo googlowania na ten temat, ale jeszcze nie widzę postmortem tego, jak ktoś rozwiązał ten problem w realnym scenariuszu. Jest some documentation for MS SQL, ale wydaje się być discouraged in MySQL, a zapisy są zasadniczo nieistniejące dla PostgreSQL.

Wydaje się, że jest to bardzo powszechny problem, ale wydaje mi się, że wiele osób pisze aplikacje internetowe i zadaje sobie kajdanki swoich użytkowników do pewnych wstępnie sprawdzonych zapytań, ale naprawdę muszę zapewnić moim użytkownikom jak największą elastyczność, przeszukuj dane za pomocą mojego klienta.

+2

Tak, bezpieczeństwo rzędu dla PostgreSQL spadło do 9.4. Obecna łata jest całkiem niezła, ale wciąż muszę naprawić co najmniej jeden błąd związany z widokami barier bezpieczeństwa w istniejącej bazie kodu, naprawić testy regresji i wykonać pewne ogólne czyszczenie, aby umożliwić wywołanie. Na 9.4 jest już za późno. –

+0

Byłoby jednak pomocne, gdybyś zamieścił dobre słowo na temat włączenia automatycznie aktualizowalnych widoków zabezpieczeń w 9.4. Użycie przez użytkownika tej funkcji może być różnicą między włączeniem a brakującym terminem. –

+0

http://www.postgresql.org/docs/devel/static/ddl-rowsecurity.html – kzh

Odpowiedz

2

Cały temat bezpieczeństwa na poziomie wiersza jest dość kontrowersyjny. Moim osobistym podejściem jest to, że szczekasz na niewłaściwe drzewo próbując zaimplementować to na warstwie ACL bazy danych. Wiem, że Oracle to popiera, ale to był naprawdę zły pomysł od samego początku i spowodował o wiele więcej frustracji niż dobra.Wiem, że czujesz pokusę ponownego użycia istniejącej funkcji kontroli dostępu tylko po to, by zaoszczędzić na liniach kodu, ale ja nie odważyłbym się pójść tą drogą tylko dlatego, że możesz skończyć w ślepym zaułku ze względu na oczekiwania wobec realności ACL. jest wdrażany w porównaniu do tego, jak chciałbyś, aby działał.

1

Zrobiłem to w Oracle i SQL Server na poziomie bazy danych, jak również za pośrednictwem serwera WWW z ustawionymi wstępnie kontrolkami autoryzacji (zapytanie nieformalne), a także za pomocą parsera SQL, który włącza formę swobodną pytanie. Moje zdanie:

 
1. Approach 1: Use database-level mechanisms, where user A is the database user 
    that creates/owns/fully controls all tables, views, and other 
    objects, and user B, C, D... are the end user accounts that utilize 
    the objects that A grants access to. 
    a. Pros 
    i. Might be easier to maintain; you may need fewer test cases to confirm that it 
     works properly 
    ii. Allows you to distribute an application that uses direct ODBC connections 
     (such as a Microsoft Access file) to multiple users, who can each have separate 
     row-level security 
    iii. Allows real-time updates to access control (either to individual permissions, 
     or to entire sets of permissions), via back-end database changes 
    iv. You don't have to worry about application security, because you are relying on 
     the database for all security (including the security of your admin account) 
    b. Cons: 
    i. Requires a separate database user account for each end user. This is generally 
     not desirable for, for example, tens of thousands of users 
    ii. By using ODBC, users are directly connecting to the database server, which could 
     be a security weakness under some circumstances (which depends on more factors than 
     are in scope for this question) 
    iii. Performance takes a significant hit. Another barrier to scalability 
    iv. For these and other reasons, this approach is generally not considered best 
     practice for production use 
    c. Implementation: 
    i. For Oracle, as you noted, there is built-in support 
    ii. For SQL Server, this can be implemented using views and instead-of triggers, 
     where the view or stored proc does SELECTs and triggers perform writes 
     in a controlled manner. This can get the job done, 
     but it is cumbersome, and requires a fair amount of code, much of which needs to 
     be changed whenever your authorization approach changes (such as changing what 
     fields in what ACL tables will authorize what actions based on what values in the 
     tables you want to secure). Furthermore, each set of code needs to be added to each 
     table you want to secure. Oracle, on the other hand, does something akin to 
     parsing the SQL statement and interjecting a where clause whenever the table you 
     are securing is involved. This is a far more flexible approach, but would be very 
     difficult to implement in SQL server unless you can write a SQL parser in T-SQL 
    iii. For postgreql and mysql, I believe you can implement the same approach as described 
     above for SQL Server, if this is the way you want to go. I suppose, in postgresql 
     you could write a SQL parser in C which performs the transformation to add the 
     necessary where clauses, make it available as a database function, pass your free- 
     form SQL to this function in your trigger or stored proc, and use the resulting 
     modified SQL as the query that gets run (or just have the C function run the query 
     and pass that back to the view). But that might be a lot of work for some added 
     flexibility for queries that you could not anticipate. 

2. Approach 2: Use an application in the middle. So either your application uses User A to log 
    in and do its stuff (not recommended, but technically, works fine), or you can set up a 
    more restricted User B just for your application, which can do everything that any end user 
    can do (e.g. view/change data), but nothing more (e.g. drop table). You rely on the 
    application to control access. 
    a. Pros: this is how most web and similar client-server applications work, and you'll find 
    lots of resources available for doing this 
    b. Cons: 
    i. you can't use this approach if you want to provide end users with an ODBC connection 
     (or an application that uses ODBC) 
    ii. As you point out, usually this is implemented in a manner that does not allow for 
     free-form SQL. There are two ways to address this latter concern: 
    A. Create your own SQL parser (this is your "proxy" solution), which your application 
     will use to parse any free-form SQL request (this will end up being similar to 
     Oracle's implementation, except that your SQL monkeying occurs in your application, 
     whereas Oracles occurs in the database). For all elements of the request that your 
     parser identifies as a table, you will perform a lookup in your ACL table to determine 
     what the "WHERE" predicate is (if any) related to that table, that will be added to 
     the SQL request before it is sent to the server. If you are familiar with creating 
     your own programming language parsers, this approach shouldn't be too hard, but if not, 
     you might not want to try-- you may find that trying to solve even simple use cases 
     ends up being just as complicated as solving any use case, so you either build a proper 
     parser that is completely flexible, or you get mired in bug fixing forever. In 
     addition, this approach will hit your performance hard just as Approach 1 does. 
    B. Create a user-interface that provides the type of query functionality you want without 
     truly being free-form. You would have to ensure the interface can support every 
     conceivable query you want to accept. While this is not ideal based on what you asked, 
     you may find it to be a more cost-effective approach given the amount of work to get 
     your SQL parser correct, if you haven't done it before, 

Ogólnie rzecz biorąc, moja rada jest taka, aby przejść z podejścia 1, jeżeli masz projekt bardzo małą skalę i będzie to zaoszczędzić czas, aby korzystać z technologii ODBC (na przykład, zrobiłem to dla pilota/test projekt, w którym stworzyliśmy aplikację w programie Microsoft Access w ciągu 2 tygodni), i poza tym, o ile elastyczność nie jest naprawdę priorytetem numer 1, a wydajność nie jest istotna, aby przejść z podejściem 2 za pomocą interfejsu strukturalnego, który pozwala aplikacji kontrolować dostęp, a także aby zapewnić większą kontrolę nad wydajnością.

0

pracuję nad takim pełnomocnika tutaj https://github.com/jbaliuka/sql-analytic Został on opracowany dla celów analitycznych/raportowania początkowo ale mam zamiar wdrożyć aplikację bramy tak, że mogę poruszać się i wykonywać SQL DB z DML pośrednictwem JavaScript z browser.It może być użyteczne jako wtyczka Olingo do publikowania bazy danych jako usługa OData.

Powiązane problemy