Affidarsi alle query parametrizzate è l'unico modo per proteggersi dall'iniezione SQL?


13

Tutto ciò che ho visto sugli attacchi di SQL injection sembra suggerire che le query parametrizzate, in particolare quelle nelle procedure memorizzate, sono l'unico modo per proteggersi da tali attacchi. Mentre stavo lavorando (nel Medioevo) le procedure memorizzate erano viste come cattive pratiche, principalmente perché erano considerate meno gestibili; meno testabile; altamente accoppiato; e bloccato un sistema in un fornitore; ( questa domanda copre alcuni altri motivi).

Sebbene quando stavo lavorando, i progetti erano praticamente inconsapevoli della possibilità di tali attacchi; sono state adottate varie regole per proteggere il database dalla corruzione di vario genere. Queste regole possono essere riassunte come:

  1. Nessun client / applicazione aveva accesso diretto alle tabelle del database.
  2. Tutti gli accessi a tutte le tabelle sono avvenuti tramite viste (e tutti gli aggiornamenti alle tabelle di base sono stati effettuati tramite trigger).
  3. Tutti gli elementi di dati avevano un dominio specificato.
  4. Nessun elemento di dati poteva essere nullo - questo aveva implicazioni che a volte i DBA digrignavano i denti; ma è stato applicato.
  5. Ruoli e autorizzazioni sono stati impostati in modo appropriato, ad esempio un ruolo limitato per dare alle sole viste il diritto di modificare i dati.

Quindi un insieme di regole (imposte) come questo (sebbene non necessariamente questo particolare insieme) sia un'alternativa appropriata alle query parametrizzate nella prevenzione degli attacchi con iniezione SQL? In caso contrario, perché no? È possibile proteggere un database da tali attacchi mediante misure specifiche (solo) del database?

MODIFICARE

L'enfasi della domanda è leggermente cambiata, alla luce delle risposte iniziali ricevute. Domanda di base invariata.

EDIT2

L'approccio di fare affidamento su query paramaterizzate sembra essere solo un passo periferico nella difesa dagli attacchi ai sistemi. Mi sembra che sia desiderabili difese più fondamentali, e che possano rendere non necessario, o meno critico, affidarsi a tali interrogativi, persino per difendersi specificamente dagli attacchi di iniezione.

L'approccio implicito nella mia domanda si basava sull'armouring del database e non avevo idea se fosse un'opzione praticabile. Ulteriori ricerche hanno suggerito che ci sono tali approcci. Ho trovato le seguenti fonti che forniscono alcuni suggerimenti per questo tipo di approccio:

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

Le principali caratteristiche che ho preso da queste fonti sono:

  1. Un vasto dizionario di dati, combinato con un vasto dizionario di dati di sicurezza
  2. Generazione di trigger, query e vincoli dal dizionario dei dati
  3. Riduci al minimo il codice e massimizza i dati

Mentre le risposte che ho avuto finora sono molto utili e indicano difficoltà derivanti dall'inosservanza delle query paramaterizzate, alla fine non rispondono alle mie domande originali (ora sottolineate in grassetto).


Non compro gli argomenti contro le stored procedure. Semplicemente non sono vere.
Konrad Rudolph,

Che succede con il requisito no-null?
Mark Canlas,

2
@Konrad Rudolph - Se scrivi l'applicazione su MySQL e poi decidi di migrare su DB2, pensi davvero che le procedure memorizzate saranno compatibili? Allo stesso modo se vuoi migrare su SQLLite? Supponiamo inoltre di aggiornare il sistema operativo: se le procedure memorizzate sono compilate in C (che sono in DB2), probabilmente avranno tutti bisogno di essere ricompilate. Questi sono argomenti ragionevoli - non assoluti, ma ragionevoli.
Matthew Flynn,

@Matthew Duh. In realtà stavo pensando a "query parametrizzate" durante la lettura e il commento. Stored procedure = storia intera.
Konrad Rudolph,

Risposte:


25

I proc memorizzati non proteggono automaticamente dall'iniezione. Che dire di questo

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

L'uso di query con parametri ti proteggerà dall'iniezione, indipendentemente dal fatto che siano in proc o meno.


Grazie per l'attenzione sulle query con parametri, piuttosto che su procs. Tuttavia, sto chiedendo se il database può essere protetto con metodi diversi da tali query, in particolare con metodi limitati al solo livello del database.
Chris Walton,

1
+1 Oltre a ciò, vorrei affermare che i proc memorizzati sono per lo più considerati sicuri perché è l'unico modo per impedire agli utenti di accedere direttamente alle tabelle pur mantenendo un modo per recuperare i dati. È l'unico modo per garantire i privilegi basati su riga e colonna quando l'utente deve avere accesso diretto al database con il suo client senza alcuna via di mezzo.
Falcon,

2
@ Chris - Penso che Craig stia dicendo che non puoi presumere che i proc in realtà ti proteggano. Forse non è una risposta completa, più una correzione dell'assunto nel titolo.
Jon Hopkins,

@Jon - Ho modificato il titolo della domanda e apportato alcune modifiche alla domanda, alla luce della correzione di Craig. Non ero a conoscenza del presupposto che stavo formulando nella domanda, fino a quando non ho iniziato a ricevere risposte.
Chris Walton,

2
Per rafforzare ciò che Craig scrive sopra, vedere databecurity.com/dbsec/lateral-sql-injection.pdf , "Iniezione SQL laterale: una nuova classe di vulnerabilità in Oracle"
Bruce Ediger,

11

Quindi un insieme di regole (imposte) come questa è un'alternativa appropriata alle procedure memorizzate nella prevenzione degli attacchi con iniezione SQL? In caso contrario, perché no?

No, perché infliggono una pesante penalità agli sviluppatori. Una suddivisione per articolo:

1. Nessun client / applicazione aveva accesso diretto alle tabelle del database.

Usa i ruoli. I client dovrebbero essere in grado di accedere al DB solo attraverso un ruolo limitato che ha accesso SELECT, INSERT, UPDATE e DELETE solo a quelle tabelle (e righe, ove possibile) a cui deve accedere. Se si desidera assicurarsi che nessun client possa inviare spam o eliminare tutte le voci, utilizzare un'API per la modifica dei dati.

2. Tutti gli accessi a tutte le tabelle erano attraverso le viste.

Potrebbe essere qualsiasi cosa, da trascurabile a un enorme costo in termini di prestazioni, a seconda dell'efficienza delle viste. È una complessità non necessaria che rallenta lo sviluppo. Usa i ruoli.

3. Tutti gli elementi di dati avevano un dominio specificato.

Potrebbe essere un sacco di lavoro da mantenere e probabilmente dovrebbe essere normalizzato in una tabella separata.

4. Nessun elemento di dati era autorizzato ad essere nulla - questo aveva implicazioni che a volte i DBA digrignavano i denti; ma è stato applicato.

Questo è semplicemente sbagliato. Se gli sviluppatori non sono in grado di gestirli NULL, hai grossi problemi.

È possibile proteggere un database da tali attacchi mediante misure specifiche (solo) del database?

Non sono necessarie procedure memorizzate, basta usare query parametrizzate con una funzione che sfugge agli argomenti, come pg_query_params . Ovviamente, se il tuo database è scrivibile in tutto il mondo o il ruolo del cliente ha pieno accesso a tutto, sei comunque fregato. Qualcuno deve solo venire avanti e rendersi conto di ciò che il client sta facendo, e quindi preparare un client in cinque minuti che distrugge (o peggio, i veleni) il tuo DB.



+1 per i ruoli. Contribuiscono in modo determinante a questo - non ho incluso ruoli nella mia domanda, ma facevano parte della configurazione - in particolare alle visualizzazioni è stato assegnato un ruolo limitato come suggerito per i clienti. Punto preso dal colpo di prestazione delle viste. I domini includevano test di validazione - principalmente intervalli e lunghezza. I tuoi commenti sulla regola nullable dei dati sono molto più educati di quelli che ho sentito parlare di questa regola. Non ho dichiarato esplicitamente che le autorizzazioni sarebbero state impostate in modo appropriato anche se questa era la mia ipotesi.
Chris Walton,

6

Non sono sicuro che le tue regole ti proteggano completamente.

Il primo problema è che dichiari di essere applicati ma, oltre a presentare un notevole sovraccarico, non ho mai visto un'applicazione perfetta.

In secondo luogo, la mia lettura è che regole come queste potrebbero rendere le cose più difficili da sfruttare ma non le impediscono. Ad esempio, non avere accesso diretto alle tabelle in realtà non cambia molto se le viste consentono di accedere agli stessi dati. Se il cliente deve fare qualcosa, una vista deve facilitarla e se una vista lo facilita, un utente malintenzionato può utilizzare le stesse funzionalità / dati.

Ricorda anche che non si tratta solo di aggiornare o eliminare i dati. Parte della vulnerabilità con SQL injection è la raccolta di informazioni e per questo non ti importa se i dati sono stati passati indietro attraverso la vista vCustomers o la tabella Clienti sottostante. Potresti esserti protetto da alcune debolezze ma non da tutte. Allo stesso modo se gli aggiornamenti possono essere effettuati dal client, anche se tramite trigger, è possibile scrivere SQL per attivare i trigger e apportare aggiornamenti.

(In termini di tutti gli aggiornamenti effettuati tramite i trigger, dirò due cose: (1) quando ho letto questo mi sono fatto un po 'male la bocca e (b) non ti piacciono le Stored Procedure perché ri "meno gestibile; meno testabile; altamente accoppiato; e bloccato un sistema in un unico fornitore" ma si utilizzano trigger su cui si può sostanzialmente dire le stesse cose.)

Tutto ciò che serve è un buco che consenta l'esecuzione di istruzioni SQL (e non vedo nessuna di queste regole che lo impediscono) e l'attaccante è dentro. Potrebbero trovare dietro di loro un database molto poco intuitivo, ma se sono determinati a farlo rallentali invece di fermarli).

L'altra cosa qui è che stai anche aggiungendo complessità e (oltre al sovraccarico che crea), la complessità tende a portare a buchi che possono essere sfruttati.

Non sto dicendo che un tale insieme di regole non possa essere creato - di più perché dovresti preoccuparti? Sembrano più ingombranti e meno affidabili rispetto ai metodi ampiamente accettati per prevenire questo tipo di attacco.


+1 per aver compreso la mia vera domanda alla luce delle mie assunzioni implicite e inconsce e per aver risposto adeguatamente. Per quanto riguarda il motivo per cui uno potrebbe preoccuparsi - sto lavorando a un progetto in cui gran parte del codice verrà generato da una descrizione rilevante dell'architettura - e parte di questa architettura descrive come generare routine di accesso al database. È ancora aperto su quale forma prenderà queste routine generate.
Chris Walton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.