2010-09-17 11 views
6

Desidero fornire agli utenti del mio sito Web accesso in sola lettura arbitrario a un database SQLite3 , senza consentire loro di scrivere sul database o fare altri danni allo . Come?Database sqlite3 di sola lettura sicuro

Rendere il file db sola lettura aiuta un po ', ma i comandi come "Attach", ".load" e ".output" permettono alle persone di leggere/scrivere altri file, che non possono essere protetti.

Naturalmente, se conoscessi tutti questi comandi, mi limiterei a filtrarli, ma sono principalmente preoccupato per i comandi a cui non ho pensato.

ho cercato brevemente di modificare il codice sorgente di sqlite3 per non consentire operazioni di scrittura, ma questo è più difficile di quanto sembri: anche l'istruzione SELECT sembra fare alcuni inserti interni/etc.

Nota:ho considerato gli attacchi DOS, e sarà ulimit cputime a 5s o qualcosa. La mia preoccupazione principale è il danneggiamento di file/"hacking", non di DOS.

chroot() può funzionare, ma sembra estremo.

Pensieri?

MODIFICA: Wow, ho davvero chiesto questo 3+ anni fa?

Da allora, I've actually written a program to do this.

che credo sia ragionevolmente sicuro (ma potrei sbagliarmi).

Here is a sample query.

+0

Immagino di essere davvero alla ricerca di una "meta-soluzione" qui. Ad esempio, se eseguissi il mio intero sistema su un CD di sola lettura, non dovrei preoccuparmi di ciò che sqlite3 può/non può fare. Nel mio caso è troppo estremo, ma l'idea generale è che voglio trovare una soluzione che funzioni senza le proprietà sqlite3. – barrycarter

risposta

1

Naturalmente, se sapessi tutte queste comandi, avevo appena filtro per di loro, ma sono per lo più preoccupati per comandi non ho pensato.

Hai mai pensato di utilizzare una whitelist anziché una lista nera? Consenti solo istruzioni che iniziano con SELECT o EXPLAIN.

+1

sqllite consente l'impilamento delle query ... – rook

+0

Sì, ma * non * è necessario autorizzarlo. Invece di sqlite3_exec, usa le istruzioni preparate, che eseguono solo una dichiarazione alla volta. – dan04

+1

Un utente che scrive query è l'esatto contrario delle istruzioni preparate. – rook

0

Assicurarsi che l'utente abbia accesso in scrittura e che altri utenti (in particolare l'utente che esegue il server Web) abbia solo accesso in lettura al file stesso. Il modo in cui ciò avviene dipende dalla piattaforma (Linux, Windows, ecc.)

+0

Giusto. Quella parte è facile. La parte difficile: quali comandi di sqlite3 possono accedere ad altri file (ad esempio, ATTACH). – barrycarter

0

Rendere il file di database letto solo nel sistema operativo. Una volta che hai finito, SQLite non può sovrascriverlo. Se hai ancora problemi, non è un problema SQLite. Potrebbero ancora essere in grado di trovare un problema php/cgi/etc, ma questa è la natura della bestia della sicurezza.

+0

Sfortunatamente, non vero (quello era il mio piano originale). Comandi come ATTACH possono accedere ad altri file. – barrycarter

+0

Se il proprio ambiente non consente l'accesso ad altri file, non c'è molto che possano fare con esso. Puoi eseguirlo in un carcere chroot? – Jay

0

Non hai menzionato come fornisci l'accesso al database SQLite.

Se lo si fa tramite l'API C (ad esempio scrivendo un CGI in C che richiede una query SQL raw, lo passa a sqlite e quindi restituisce ciò che è stato restituito), quindi i comandi punto come ".load" sono di nessuna preoccupazione. Questi sono implementati dal sqlite3 shell program e non funzioneranno quando si chiamano direttamente le funzioni API C.

In questo caso è possibile chiamare sqlite3_open_v2 passando SQLITE_OPEN_READONLY come uno dei flag per impedire la scrittura del database.

Il comando ATTACH può essere disabilitato chiamando sqlite3_limit() per impostare SQLITE_LIMIT_ATTACHED su 1 per impedire il collegamento di un secondo database da esito positivo. Poiché l'istruzione DETACH "scollega una connessione di database aggiuntiva precedentemente collegata utilizzando l'istruzione ATTACH", sembra che questo impedisca a uno di staccare il database originale per aggirare questa restrizione.

Per quanto ne so dall'osservazione dello SQL understood by SQLite, questo dovrebbe chiudere tutti i buchi. Potresti passare attraverso lo pragmas con un pettine a denti stretti solo per essere sicuro, se c'è qualcosa che mi è mancato fammelo sapere e aggiornerò questa risposta.

Problemi correlati