Sicurezza: blacklist di tabelle e colonne
Il vero confine di sicurezza vive in src/Config.php, non nella chiamata ->columns() di una singola pagina.
->columns() non è un confine di sicurezza
Chiamare ->columns('name', 'email') su una pagina cambia solo ciò che la griglia di quella pagina mostra. Non ha alcun effetto su core/ajax_crud.php, l'endpoint REST con cui dialoga davvero il JavaScript di ogni widget - l'API risolve la configurazione di una pagina rieseguendo la sua rotta (xcrud_load_hooks_from_page()), ma le colonne esposte da una vera tabella del database sono governate dallo schema della tabella stessa, non da ciò che una pagina ha scelto di mostrare. Un visitatore che chiama l'API direttamente (apre DevTools, ripete la richiesta con un route/query diversi) non è limitato in alcun modo dal restringimento imposto dal ->columns() di una pagina.
In altre parole: ->columns() è una comodità di visualizzazione. Non è mai ciò che si frappone tra una colonna sensibile e la rete.
$blacklistedTables - il vero confine a livello di tabella
Ogni vera tabella del database connesso è raggiungibile tramite Xcrud per impostazione predefinita (introspezione live, nulla da registrare prima) - $blacklistedTables in src/Config.php è ciò che rimuove del tutto una tabella dalla portata, indipendentemente da cosa provi a fare il PHP di qualunque pagina:
public static array $blacklistedTables = [
'sys_settings', 'sys_settings_other', 'sys_notifications', 'logs',
];
Una tabella in blacklist non può mai essere raggiunta tramite ->table(), come target di ->relation(), né come tabella figlia di ->gallery() - chiamare ->table('logs') genera immediatamente un'eccezione invece di renderizzare silenziosamente una griglia vuota.
$blacklistedColumns - blocco a livello di colonna
Alcune tabelle vanno bene da esporre in generale ma hanno colonne specifiche che non dovrebbero mai transitare tramite l'API - un hash di password, un token interno, una colonna blob legacy. $blacklistedColumns blocca quelle colonne all'interno di una tabella altrimenti raggiungibile, indicizzata per nome tabella:
public static array $blacklistedColumns = [
'user' => [
'password', 'confirm_password', 'session',
'remember_token', 'remember_token_expires',
'confirmation_code', 'app_key',
],
'customers' => ['avatar'],
'productlines' => ['image'],
];
Una colonna qui elencata è nascosta e bloccata in scrittura - non viene mai restituita in una risposta JSON di lista/form e non viene mai accettata in inserimento/aggiornamento, indipendentemente da cosa richieda la chiamata ->columns()/->fields() di qualunque pagina. È proprio questo a rendere effettivamente sicuro esporre una tabella come user: la tabella stessa non ha bisogno di finire in blacklist solo perché lo fa una sua colonna sensibile.
$appSecret - firma, non blacklist
Una questione correlata ma distinta: $appSecret firma con HMAC le condizioni ->where()/->subselect()/->pass_var() e i payload delle logic-condition prima che viaggino attraverso il browser, cosicché ajax_crud.php possa rifiutarsi di applicare una condizione la cui firma non corrisponde. Protegge lo scoping intenzionale di una pagina (ad es. "mostra solo gli ordini di questo cliente") da manomissioni lato client - non sostituisce la blacklist di tabelle/colonne descritta sopra. Vedi Distribuzione in produzione per generare un valore robusto prima del lancio.