02 - Database DB2 for i02a - SQL02b - Tuning e Amministrazione DB04f - Sicurezza

Il mascheramento dei dati sensibili con DB2 ed SQL

Le sempre più sofisticate normative sulla privacy dei dati, insieme alle policy che le singole aziende adottano su questa materia, fanno sì che in alcuni casi sia necessario impedire la visualizzazione di dati sensibili ad utenti non autorizzati. Le applicazioni aziendali possono essere state sviluppate considerando questo requisito, ma il DB2 incorpora infatti delle istruzioni SQL che permettono di soddisfare molto facilmente questa esigenza in modo automatico e a livello di sistema, grazie a due caratteristiche principali:

  • il controllo di accesso a livello di riga e colonna (RCAC – Row and Column Access)
  • gli oggetti di tipo MASK – maschere a livello di singola colonna

Vediamo qui in particolare come è possibile creare un filtro che consenta la visualizzazione di un campo di un file solo agli utenti autorizzati.

Per poter attivare questa funzione i prerequisiti sono i seguenti:

  • IBM i 7.2 o superiore
  • avere installato il prodotto 5770SS1 opzione 47 Advanced Data Security for i
  • l’utente che attiva il mascheramento deve essere registrato come amministratore del DB
  • La tabella sulla quale si vuole applicare la maschera deve avere attivato il controllo di accesso a livello di colonna

Per verificare la presenza dell’opzione 47 è sufficiente il consueto comando GO LICPGM, scelta 10

Per autorizzare un utente alla gestione del DB non sono sufficienti i privilegi “standard” come *SECADM o *SECOFR, ma l’utente va iscritto in un apposito registro a cui si accede con il comando WRKFCNUSG (Work with Function Usage). Lanciando il comando senza indicare parametri, la schermata che appare è la seguente:

L’ID della funzione che ci interessa è QIBM_DB_SECADM. Con l’opzione 2 su questa funzione possiamo aggiungere l’utente autorizzato.

Per verificare questo tipo di autorizzazioni possiamo controllare la view del catalog QSYS2.FUNCTION_USAGE

Infine, attiviamo il controllo di accesso a livello di colonna (RCAC) per il nostro file:

ALTER TABLE mduca1.custm00f        
ACTIVATE COLUMN ACCESS CONTROL  

Una volta completate le impostazioni, possiamo passare all’azione: in un file anagrafico clienti vogliamo che solo gli utenti autorizzati possano vedere la ragione sociale. L’istruzione SQL che attiva il mascheramento di colonne è CREATE MASK. Per il nostro file usiamo questa istruzione:

CREATE OR REPLACE MASK cust_name_mask ON mduca1.custm00f        
FOR COLUMN  custname RETURN                          
CASE WHEN (SESSION_USER <> 'QSECOFR')               
     THEN '----------'   
     ELSE custname                                   
END                                                  
ENABLE  

La regola qui è abbastanza elementare, se l’utente non è QSECOFR, al posto della ragione sociale si vedranno 10 trattini. Questa regola può ovviamente essere più sofisticata; per esempio è possibile richiamare una apposita function personalizzata per determinare chi può vedere il dato e chi no.

CREATE OR REPLACE MASK cust_name_mask ON mduca1.custm00f        
FOR COLUMN  custname RETURN                          
CASE WHEN (checkAuthCustname(SESSION_USER) <> '1')               
     THEN '----------'   
     ELSE custname                                   
END                                                  
ENABLE 

Se la funzione checkAuthCustname restituisce ‘1’, l’utente della sessione corrente potrà avere accesso al dato.

La clausola ENABLE fa sì che venga attivato il mascheramento per la colonna, che può quindi essere attivato e disattivato secondo le necessità.
Proviamo a verificare: collegandosi con un utente non autorizzato ed interrogando il file, non si ha accesso al campo con la ragione sociale:

Collegandoci invece con l’utente autorizzato (QSECOFR), ecco il risultato:

Interessante notare che le maschere SQL funzionano a fronte di qualsiasi comando di sistema che visualizzi il dato mascherato, per cui anche uno sviluppatore non autorizzato che eseguisse un semplice DSPPFM non avrebbe comunque accesso al dato sensibile.

Per cancellare una maschera, nulla di più facile…

DROP MASK mduca1.cust_name_mask 

Le maschere DB2 si possono anche disattivare temporaneamente, senza necessariamente cancellarle. Ecco l’istruzione:

ALTER MASK cust_name_mask DISABLE  

Per disattivare del tutto il controllo di accesso di colonna per un file, l’istruzione è questa:

ALTER TABLE mduca1.custm00f        
DEACTIVATE COLUMN ACCESS CONTROL  

Fin qui tutto bello… ma cosa succede se un utente non autorizzato eseguisse un normale programma che aggiorna quel file ? Di seguito il source di un semplicissimo programma che legge un record del file “mascherato” CUSTM00F ed aggiorna il campo city. L’aggiornamento viene eseguito con una istruzione UPDATE, per cui di fatto vengono impattati tutti i campi del file.

       ctl-opt option(*srcstmt:*nodebugio) ;                     
       dcl-f Custm01l disk(*ext) keyed usage(*input:*update) ;   
       dcl-s  cust    char(8) ;                                  
       //----------------------------------------------------    
        *inLR=*on;                                               
                                                   
        cust = '00003256' ;                                      
        chain (cust) Custm01l;                                   
        if %found(Custm01l);                                     
           city = 'LAS VEGAS';                                   
           update Custm;                                         
        endif;                                                   
                                                                 
        return;                                                  

Se eseguiamo il programma dopo il login con un utente non autorizzato, ecco cosa succede:

Allarme ! Il programma ha aggiornato anche il campo custName con il valore mascherato !
Questo problema apparentemente grave si può risolvere facilmente attivando una check constraint (vincolo di controllo) sul file, in modo da intercettare il valore mascherato ed impedire che venga scritto effettivamente nel DB.

ALTER TABLE mduca1.custm00f
ADD CONSTRAINT cust_name_mask_ck
CHECK (custname <> '----------')
ON UPDATE VIOLATION PRESERVE custname;

Con questa istruzione, diciamo al DB2 di non accettare un valore pari a 10 trattini nel campo custname del file CUSTM00F; quando il DB2 intercetta una violazione a questa regola mantiene il valore del campo (ON UPDATE VIOLATION PRESERVE custname).
Dopo avere ripristinato il valore precedente del campo custname ed avere attivato la constraint, proviamo a rilanciare lo stesso programma di prima e vediamo questa volta cosa succede…

Adesso, tutto OK !

Per elencare tutte le maschere presenti nel sistema, si può sfruttare la view QSYS2.SYSCONTROLS:

CREATE MASK e tutte le funzioni correlate si possono tranquillamente usare sia per tabelle SQL che per i classici file fisici definiti con le DDS. Sfruttando le maschere SQL, ed attivando le opportune constraint, è possibile sviluppare le proprie applicazioni senza preoccuparsi di implementare il mascheramento, che verrà gestito automaticamente dal DB2.

DOCUMENTAZIONE:
Istruzione CREATE MASK: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/db2/rbafzcrtmask.htm
View FUNCTION_USAGE: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzajq/rzajqviewfuncusage.htm
View SYSCONTROLS:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/db2/rbafzcatsyscontrols.htm
Comando WRKFCNUSG:
https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/cl/wrkfcnusg.htm

About author

Senior Analyst/Developer e divulgatore in ambito IBM i. Già collaboratore dell'edizione italiana della rivista "System i News" ed autore di diverse pubblicazioni su tools e tecniche di sviluppo in ambiente IBM i.

Rispondi

%d blogger hanno fatto clic su Mi Piace per questo: