Newsgroup: it.comp.software.database
Titolo: sicurezza & pg

un link circa la sicurezza del DB postgresql:
http://www.rctecno.net/PG-sec.htm

 
http://www.rctecno.net/PG-sec.htm
La frase chiave mi sembra sia:
"Nella sostanza l'architettura di sicurezza dovrà essere ridefinita
in modo che il database server restituisca, anche a fronte d'una
"SELECT *" su d'una tabella, solo i record di competenza dell'utente
loggato."
Il concetto di "competenza di una riga" mi sembra una cosa
abbastanza particolare e sostanzialmente limitata a un
particolare problema specifico meglio gestibile lato client;
prevedere un sistema di autorizzazioni esteso a tutto il db mi
sembra eccessivo.
Devo inoltre far notare il potenziale pericolo di tale meccanismo,
che in vari casi dara' origine a dati incongruenti (ad es. un
join che non abbia i permessi sulla tabella esterna fara'
sparire anche le righe "mie"; un vincolo PK/FK potrebbe farmi
vedere solo le righe nella FK senza i necessari corrispettivi
nella PK; eppure un inserimento nella PK mi darebbe un inaspettato
errore di violazione di chiave, etc...).
In teoria relazionale una riga mancante in una tabella ha un
significato preciso, ossia che l'istanza del predicato e' FALSE.
VoliDiLinea {NomePasseggero, Aereo}
Terroristi {Nome}
Se un join sulle tabelle sopra ti da' come risultato un insieme
vuoto, significherebbe che su quel determinato volo non ci
sono terroristi, mentre invece il dbms potrebbe avermeli resi
sciaguratamente "invisibili".
In definitiva la differenza fondamentale e' che si potrebbero far
passare silenziosamente degli errori che col sistema di
autorizzazioni "classico" verrebbero intercettati con un sano
errore bloccante.
(Gli errori non sono necessariamente negativi; dobbiamo pensare
ad essi come ad un salvavita che scatta l'istante prima di
essere fulminati).
bye 

trovo la risposta molto interessante.  Tuttavia mi permetto di far
notare che nella fattispecie viene
ipotizzato uno scenario in cui v'e' stato un errore nella
configurazione dei permessi d'accesso ai dati.
Anche sul piu' classico "file-system", se una cartella non e'
scrivibile, mentre l'applicazione s'aspetta
il contrario, si puo' generare un errore (o non generarsi, se
l'applicazione non ha gestito il caso!).
Sarebbe peraltro interessante capire una cosa, aprendo una questione
che si pone al confine fra
teoria dei DB relazionali e filosofia pura: quando scrivi  "In teoria
relazionale una riga mancante in una
tabella ha un significato preciso, ossia che l'istanza del predicato
e' FALSE" ci si potrebbe chiedere
se la proposizione possa essere considerata vera, rispetto al
soluzione proposta, nel caso in cui
si intenda per "tabella" non tanto l'insieme di record complessivo, ma
solo quelli dell'utente ai quale
si intende di voler dare accesso.
In ogni caso, da un punto di vista teorico/formale, il tuo post e'
certamente ineccepibile. Rimane pero'
il fatto che, senza applicare la soluzione proposta, a livello di
regole sul DB, ma volendo comunque
un livello di sicurezza che non dipenda dal client, l'unica soluzione
sembra l'introduzione d'un
application server. Tale architettura e', tuttavia, onerosa e non
applicabile a programmi gia' esistenti.
In ultima analisi, personalmente, ritengo che una accettabile
soluzione non lo debba essere solo in
termini tecnici (o teorici), ma anche in termini di costi.
bye


 (o teorici), ma anche in termini di costi.
A parte che una non esclude l'altra...
Io chiedo spesso "Quanto vi costa un errore? Quanti errori volete
tollerare?". Vedrai che sara' il cliente stesso a dirti "Nessuno".
bye bye

 join di molte tabelle).
PS: un altro cambiamento rispetto al modo solito di operare di
un dbms potrebbe essere una violazione di chiave gia' esistente:
se una chiave e' stata inserita da un altro utente ma io non
vedo la riga, dovrebbe il dbms impedirmi di inserire lo stesso
valore?
Se si, allora io vengo ugualmente a sapere che quella riga esiste...
Se no, allora mi sballa il concetto di chiave primaria ed ho
tanti database quanti sono i permessi.
PS2: Come si comportano gli operatori di aggregazione?
Potrei avere dati diversi a seconda di come recupero le righe
(es. SUM() contro riga per riga...).

credo che per ogni esempio che si possa fare per NON usare le regole
proposte (terroristi, allergie, ...)
se ne possano trovarne altrettanti per usarle (transazioni
finanziarie, genetica, ...).  Quindi, non m'oppongo
ai casi specifici.
Circa i permessi, concordo: vale il più restrittivo. Ma, ancora una
volta, e' sempre uno svantaggio? Una
delle tecniche d'attacco ai sistemi, guarda caso, e' detta "escalation
dei privilegi" ...
In merito al fatto di considerare "pericolo" l'ottenere una risposta
"tabella vuota", quando non lo e', lascio
a ciascuno dei fruitori del metodo proposto decidere quanto sia, in
ciascun caso, pericoloso.
Sull'aggregazione, i costrutti SQL opererebbero esattamente come se
operassero su delle viste, quindi,
non vedo ambiguita'.
Riguardo la supposta pretesa che un cliente non voglia perdere alcun
dato sono in disaccordo. Una buona
analisi dei rischi NON parte dal presupposto di non dover perdere
alcun dato, ma di chiedersi quanto
costerebbe evitare di perderlo. Spesso, nella vita reale, la difesa ad
oltranza d'un entita' ha un costo
maggiore che non gestir la perdita della stessa (ovvero: hai blindato
la tua casa con un sistema del costo
di qualche milione di euro, nell'illusione che sia sicura?).

 finanziarie, genetica, ...) [...]
Puntualizzo che non era una questione di trovare un argomento
"drammatico" (forse l'esempio ha distolto l'attenzione), ma il
fatto che il dbms dice due cose contraddittorie.
Infatti il punto fondamentale e' la sostanziale differenza
tra il riportare un errore di "Access denied" e nascondere
alcune righe. Questo puo' aprire la porta ad incongruenze.
A tal proposito, non vedo la risposta al primo post scriptum.
Gli altri argomenti sono giusti di per se', ma dipendono da
quanto sopra. 

 tanti database quanti sono i permessi.
In attesa di risposta, ecco un'altra situazione-tipo:
un c/c con 1.000 Euro
C/C {Euro, Causale}
-----------------------------------
1000    Saldo iniziale
"Buongiorno Cassiere A, quanti soldi ho?". "1000 Euro" "Me li dia"
-1000   Prelievo Cassiere A
"Buongiorno Cassiere B, quanti soldi ho?". "1000 Euro" "Me li dia"
-1000   Prelievo Cassiere B
Direttore: "Siamo in rosso di 1000 euro, chi e' stato?"
Cassiere A:
Select * from C/C
C/C {Euro, Causale}
-----------------------------------
1000    Saldo iniziale
-1000   Prelievo Cassiere A
Saldo Finale: Sum(Euro) = 0 "Per me e' a posto"
Cassiere B:
Select * from C/C
C/C {Euro, Causale}
-----------------------------------
1000    Saldo iniziale
-1000   Prelievo Cassiere B
Saldo Finale: Sum(Euro) = 0 "Anche per me e' a posto"
Direttore:
Select * from C/C
C/C {Euro, Causale}
-----------------------------------
1000    Saldo iniziale
-1000   Prelievo Cassiere A
-1000   Prelievo Cassiere B
Saldo Finale: Sum(Euro) = -1000 "Per me no!"
Se ciascun cassiere vedesse solo i record di propria competenza,
assieme darebbero piu' soldi di quanti versati. Questo e' solo un
banale esempio che vuole illustrare come tale sistema intacca la
logica delle operazioni derivate.
Nascondere una riga non e' una semplice questione di "presentazione
all'utente" (da gestire meglio in altro layer), ma un cambiamento
sostanziale nel modo di operare del database.
Un meccanismo di sicurezza non deve permettersi di cambiare
i valori nelle tabelle, in nessuna maniera; proprio non e' un
campo che gli compete. 

Ancora una volta l'esempio specifico e' corretto. Tuttavia, in un
sistema
basato su permessi, tipicamente esiste chi puo' piu' degli altri.
Quindi,
nell'esempio, il titolare del negozio potrebbe ricostruire
correttamente
la situazione, avendo accesso a tutti i dati.
NON e' mi intenzione affermare che e' SEMPRE corretto applicare
la proposta di miglioramento di sicurezza. E' mia intenzione affermare
che,
in ALCUNI casi, e' una soluzione migliore del non farlo.
Circa la collisione sulle PK, in effetti, si verrebbe a conoscenza,
indiretta,
dell'esistenza d'una riga. Il dato, in tal caso, e' significativo solo
se la
PK non e' definita come SERIAL (o simile), ma e' parlante.