6

Sto cercando uno schema valido per implementare controlli di sicurezza a livello di riga (tramite ad esempio un proxy, un servizio Web man-in-the-middle o stored procedure) idoneo all'uso in un ambiente client-> database. Controllo sia il client che il database. Alcuni requisiti:Sicurezza a livello di riga in uno scenario di database client

  • Proibire agli utenti di visualizzare le righe nella query risultati che non hanno il permesso di vedere
  • Permettere agli utenti di inserire e aggiornare i propri righe nella tabella, che dà loro il permesso di vederli
  • (requisito morbido) che consente agli utenti di concedere ad altri l'accesso per leggere o scrivere le proprie righe
  • Una soluzione open source oa basso costo che gira su Linux. A quanto ho capito, nessun database libero implementa la sicurezza a livello di riga in quanto tale. Oracle supporta questo, ma è troppo costoso $$$$. Postgres might be implementing this in 9.4, ma era originariamente mirato per 9.3 e scivolato e non vi è discussione sulla ML che potrebbe scivolare di nuovo. Sto vagamente pensando di usare Postgres solo perché sembrano il più lungo in questa funzione.

Alcuni (non particolarmente buone) idee che ho avuto:

  • vista barriera di sicurezza di usare PostgreSQL e nego l'accesso degli utenti alla tabella sottostante. Sfortunatamente c'è no good way to insert a row into a security barrier view, quindi alcuni proxy/webservice privilegiati dovrebbero gestire le istruzioni di inserimento. Questo sembra difficile da ottenere.
  • Utilizzare le viste normali e negare all'utente l'accesso alla tabella sottostante. Ciò consente insert, ma avrei bisogno di bloccare le autorizzazioni in modo piuttosto rigido (ad esempio nessuna funzione di creazione) e there seem to be a lot of gotchas (like divide by zero) that leak information.
  • Definire un sottoinsieme di SQL e creare un proxy che è l'unico punto di comunicazione con il database. Il proxy analizza la query SQL e la riscrive per far rispettare i requisiti di sicurezza. Questo sembra difficile da fare in generale, ma forse potrei farla franca con un sottogruppo SQL molto piccolo fino a quando postgres implementerà la sicurezza a livello di riga per davvero.
  • Basta avere tabelle diverse per utenti diversi (o anche diversi DB). Tuttavia non sono sicuro di quanto bene questo ridimensiona a molti utenti. Inoltre, questo non sembra soddisfare il requisito morbido.
  • Trovare qualche DB commerciale ma ragionevole costo che supporta in realtà questo
  • Usa Veil, ma non sembra essere mantenuto, e ha la maggior parte delle limitazioni di altre soluzioni

Ho fatto un molto sul googling su questo argomento ma devo ancora vedere un post-mortem su come qualcuno ha risolto questo problema in uno scenario del mondo reale. C'è some documentation for MS SQL ma sembra essere discouraged in MySQL e le scritture sono praticamente inesistenti per postgres.

Questo mi sembra un problema molto comune, ma credo che molte persone stanno scrivendo applicazioni web e si accontentano di ammanettare i loro utenti a determinate query pre-controllati, ma ho davvero bisogno di dare ai miei utenti la massima flessibilità possibile per interrogare i dati con il mio cliente.

+2

Sì, la sicurezza di riga per PostgreSQL è scivolata per 9.4. La patch corrente è abbastanza buona, ma devo ancora correggere almeno un bug relativo alle viste della barriera di sicurezza nella base di codice esistente, correggere i test di regressione e fare una pulizia generale per renderla committibile. È troppo tardi per 9.4. –

+0

Sarebbe utile se si inserisse una buona parola per l'inclusione delle viste di barriera di sicurezza aggiornabili automaticamente in 9.4, comunque. La spinta dell'utente su quella caratteristica potrebbe essere la differenza tra l'inclusione e la scadenza mancante. –

+0

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

risposta

2

L'intero argomento di sicurezza a livello di riga è piuttosto controverso. La mia opinione personale su questo è che stai abbaiando all'albero sbagliato cercando di implementarlo nel livello ACL del database. So che Oracle lo supporta, ma è stata una pessima idea fin dall'inizio e ha causato molto più frustrazione che bene.So che ti senti tentato di riutilizzare le funzionalità di controllo degli accessi esistenti solo per risparmiare su righe di codice, ma io stesso non oserei percorrere questa strada solo perché potresti finire in un vicolo cieco a causa delle aspettative rispetto alla realtà di come l'ACL è implementato rispetto a come vorresti che funzionasse.

1

Ho eseguito questo in Oracle e SQL Server a livello di database, nonché tramite un server Web con controlli di autorizzazione preimpostati (query non in forma libera), nonché tramite parser SQL che consente la forma libera query. Il mio prendere:

 
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, 

complesso, la mia raccomandazione è di andare con Approccio 1 se si dispone di un progetto molto piccola scala e che vi farà risparmiare tempo per utilizzare ODBC (ad esempio, ho fatto questo per un pilota/test progetto in cui abbiamo creato l'applicazione in Microsoft Access in 2 settimane), e in caso contrario, a meno che la flessibilità sia veramente la priorità numero 1 e le prestazioni non siano importanti, per andare con Approach 2 utilizzando un'interfaccia strutturata che consente all'applicazione di controllare l'accesso, e anche per fornire un maggiore controllo sulle prestazioni.

0

Sto lavorando su tale delega qui https://github.com/jbaliuka/sql-analytic E 'stato sviluppato per scopi di reporting/analisi inizialmente, ma ho intenzione di implementare applicazioni gateway in modo che io possa navigare DB ed eseguire SQL con DML tramite JavaScript da browser.It potrebbe essere utile come il plugin Olingo per pubblicare il database anche come servizio OData.