L'esecuzione di SQL tramite un WebService è una pessima idea?

6

Tipicamente quando si crea uno strumento semplice o qualcosa che deve usare un database, passo attraverso il processo piuttosto lungo di creare prima un servizio web che si connette a un database e quindi creare metodi su questo webservice che fanno tutto il tipo di query che mi servono .. metodi come

List<Users> GetUsers()
{
    ...
}
User GetUserByID(int id)
{  
    ...
}
//More Get/Update/Add/Delete methods

È terribile progettare semplicemente rendere il servizio web il più sicuro possibile (non sono proprio sicuro di come fare qualcosa del genere) e fare solo un paio di metodi come questo

SqlDataReader RunQuery(string sql)
{
     ...
}

void RunNonQuery(string sql)
{
     ...
}

Sarei come esporre il mio database a Internet, suppongo, che suona male ma non ne sono sicuro.

Mi sento come se stessi sprecando così tanto tempo a eseguire tutto attraverso questo servizio web, ci deve essere un modo più rapido e sicuro che non coinvolge la mia applicazione che si collega direttamente al database (l'applicazione non può connettersi direttamente al database perché il database non è aperto a nessuna connessione ma localhost, e dove l'appliczione risiede le porte sql standard sono bloccate comunque)

Specialmente quando ho solo bisogno di eseguire alcune semplici query

    
posta Kyle 04.07.2012 - 17:06
fonte

10 risposte

12

È un design terribile e tu lo sai. Ti stai lasciando in balia di chiunque abbia anche un leggero intento malevolo. Oltre ad essere vulnerabile alla normale iniezione SQL, si espone un intero webservice per creare SQL, ignorando anche la necessità di iniettarlo. Fare una cosa del genere con il tuo database privato è semplicemente poco saggio, farlo con il database di produzione di un cliente potrebbe anche potenzialmente aprirti a conseguenze legali se i contenuti sono trapelati.

Utilizza un ORM se non lo usi già, potrebbe darti il risparmio di tempo che stai cercando.

    
risposta data 04.07.2012 - 17:26
fonte
5

I just feel like I waste so much time running everything through this webservice, there has to be a quicker yet safe way that doesn't involve my application connecting directly to the database (the application can't connect directly to database because the database isn't open to any connections but localhost, and where the appliction resides the standard sql ports are blocked anyway)

Perché non basta cambiare il database per aprirlo a qualsiasi connessione? Scrivendo questo servizio web è ciò che stai facendo. (in modo un po 'indietro)

Avrei anche grandi preoccupazioni sul fatto che la codifica HTTP possa cambiare il significato di alcune delle istruzioni SQL causanti errori. (potenzialmente distruttivi)

    
risposta data 04.07.2012 - 18:34
fonte
4

L'unico problema reale con questo è la sicurezza .. Poi c'è il fatto che hai un'API che non è definita affatto, ma potresti non interessartene.

Ma se questo è un servizio web " Privato " (richiede credenziali e ha un insieme molto piccolo di utenti fidati) non vedo nulla di sbagliato in questo.

Ok, Confesso .. Ho (per creare app distribuite) Aprire le porte DB su Internet e Connesso le mie app FAT direttamente al DB su Internet, facendo affidamento solo sul Protezione DB per protezione . Questo mi ha salvato settimane di lavoro.

Vorrei anche sottolineare che tutti gli strumenti di gestione dei DB online fondamentalmente fanno qualcosa di simile a questo (MySql Admin per esempio) ..

    
risposta data 04.07.2012 - 17:22
fonte
2

Questo non funziona su 2 livelli:

  • Ovviamente la sicurezza è un problema
  • Il tuo altro problema è di progettazione. Se chiami GetSomePeople dal servizio wweb è più facile sganciare successivamente la tua app dal database. Tutto ciò che devi fare è implementare GetSomePeople in qualsiasi nuova tecnologia tu scelga.

L'ultima domanda è perché vorresti farlo? Hai passato così tanto tempo a fare questa domanda che qualcosa ti sta già dicendo di non farlo. Se hai appena proseguito con il servizio web, probabilmente lo avresti già fatto:)

Un buon design non è mai una perdita di tempo!

    
risposta data 04.07.2012 - 17:54
fonte
1

Sì, questa è una cattiva idea, dal punto di vista della sicurezza. Potrebbe consentire l'esecuzione di un select credit_card_numbers from credit_card_accounts o drop table users se qualcuno capisce cosa fa il tuo servizio e come inviare messaggi direttamente ad esso.

C'è un motivo per cui non è possibile avere stored procedure (una per ogni query / istruzione che è necessario eseguire) che richiedono alcuni input chiave che il servizio Web passa loro e un'operazione di webservice per ogni proc memorizzato? Potresti anche creare una sola operazione e potrebbe richiedere un nome di procedura memorizzato e un elenco di input. Non buono come operazioni separate, ma ancora meglio di SQL arbitrario.

L'unica ragione per cui posso pensare al webservice di prendere SQL arbitrario ed eseguirlo sarebbe per un ambiente sandbox / testing che si trova su una rete isolata e se succede qualcosa di brutto, può essere cancellato e ripristinato alla base immagine facilmente.

    
risposta data 04.07.2012 - 17:34
fonte
1

Hai cercato un framework? per esempio. Se stai programmando in Java ti consiglio di investire 5 giorni imparando le basi di Spring con i suoi strumenti REST e Hibernate. Oppure trova un framework simile per il tuo linguaggio di programmazione.

Ho imparato molto tempo fa che se un problema richiede di scrivere un sacco di codice banale, alcuni buoni programmatori altrove hanno probabilmente costruito alcuni strumenti / framework per renderlo più semplice.

Un buon framework risolverà molti dei tuoi problemi, inclusi alcuni che non hai ancora pensato. Lo renderà anche più gestibile per un altro programmatore. E ottieni alcune parole d'ordine per il tuo curriculum.

    
risposta data 04.07.2012 - 20:05
fonte
1

Non dici nulla di che tipo di "strumenti semplici" di cui stai parlando, quindi ottieni solo delle risposte istintive basate su ciò che la gente pensa che sia.

Se gli strumenti sono app desktop distribuite a utenti non fidati su Internet, ovviamente sarebbe una pessima idea non permettere loro di eseguire arbitrariamente SQL sul server del database. D'altra parte, se lo strumento è uno strumento di amministrazione eseguito da solo o una webapp in esecuzione su un server trusted, potrebbe essere opportuno ritagliare l'intermediario e chiamare direttamente al database. Quindi la risposta è: Dipende!

In ogni caso, la soluzione sembra essere a metà cottura. Se non ti fidi abbastanza dei client per fornire loro una connessione diretta al database, allora non dovresti permettere loro di eseguire arbitrariamente SQL. Se il tuo amministratore di sistema disabilita le connessioni al database per motivi di sicurezza, probabilmente non dovresti tentare di aggirare questo problema con il "tunneling" di SQL arbitrario attraverso un servizio web.

    
risposta data 27.06.2015 - 10:05
fonte
0

Ovviamente questo non va bene da un punto di vista della sicurezza, come hanno sottolineato tutti.

Ma è altrettanto negativo dal punto di vista della gestione del database. Come ti assicuri:

  • le query sono scritte in modo competente?
  • utilizzerà gli indici?
  • tratterà con garbo inserzioni / aggiornamenti con garbo
  • non incontrerà problemi di blocco permanente?

In breve, non c'è modo in cui questa sia una buona idea.

    
risposta data 04.07.2012 - 19:19
fonte
0

Qui interpreterò l'avvocato del Diavolo e dirò "forse no". Il problema principale è la sicurezza, che verrò più tardi.

Alzi la mano se sei un fan del modello relazionale. Per molti domini, è l'unico che abbia senso. SQL è il linguaggio serio solo che abbiamo per chiedere domande arbitrarie (non predefinite) su un determinato set di dati.

Con un tradizionale servizio web basato su HTTP, ci si limita a porre le domande a cui il progettista dell'API ha pensato (e potrebbe essere preso la briga di implementare). Certo, puoi prendere tutti i dati che puoi e fare i "join" dalla tua parte, perdendo i benefici del modello relazionale. Questo percorso è pieno di bug, sforzi duplicati, fragilità e il resto.

Se vuoi che i consumatori della tua API di dati siano in grado di porre domande che non conosci in anticipo, SQL è la lingua migliore.

Ovviamente la sicurezza è il motivo per cui la tua domanda innesca così tante bandiere rosse, e non ci sono le migliori pratiche da seguire, perché quasi nessuno permette l'accesso a livello SQL in primo luogo.

Alcuni database consentono di limitare gli utenti a un insieme di viste particolari e possono impedire operazioni distruttive ( INSERT , DELETE , ecc.), evitando che molti dei problemi di iniezione sollevati da altre risposte. Consentire solo l'accesso basato sulla vista consentirebbe anche un grado di disaccoppiamento dalla struttura della tabella effettiva.

Infine, Tom Squires sottolinea giustamente che HTTP non sta aggiungendo molto valore qui. Potresti anche consentire solo connessioni dirette DB.

    
risposta data 23.10.2012 - 21:36
fonte
0

Le persone non stanno criticando solo dicendo che non è una buona idea.

WCF è un'alternativa.

Non è come esporre il database a Internet - sta esponendo il database a Internet. Le porte sono bloccate per un motivo. Non è solo un rischio per la sicurezza in generale, ma chiaramente violerebbe la tua politica di sicurezza. La persona / gruppo che ha bloccato quelle porte sarebbe molto scontento di te.

Come per "Specialmente quando ho solo bisogno di eseguire alcune semplici query"
Nulla dice che non puoi avere un metodo generale

void RunNonQuery(Int id)
{
     ...
}

Forse non è il miglior design, ma almeno non stai passando SQL

Con WCF penso che puoi restituire un DataTable e SqlDataReader in modo che tu possa fare come

SqlDataReader RunQuery(Int id)
{
     ...
}

Forse non è il miglior design ma è sicuro

Diciamo che non c'erano dati sensibili che si potesse avere una connessione di sola lettura con un breve timeout per proteggersi dagli attacchi di tipo denial of service

SqlDataReader RunQuery(String SQL)
{
    ...
}

Ma dubito seriamente che avresti passato quella gente della sicurezza Se vuoi fare qualcosa del genere, assicurati che sia approvato dalla sicurezza Non vuoi che qualcuno scopra solo che lo stai facendo Devi ottenere l'autorizzazione in anticipo

Strumento semplice o qualcosa che deve usare un database
È solo un un database
Se i dati non devono essere condivisi, prendere in considerazione un database incorporato

Lo strumento deve essere app desktop? Può essere un'applicazione web?

    
risposta data 27.06.2015 - 14:58
fonte

Leggi altre domande sui tag