Domanda:
Perché non posso semplicemente consentire ai clienti di connettersi direttamente al mio database?
Moritz Friedrich
2020-04-17 17:45:14 UTC
view on stackexchange narkive permalink

Sono abbastanza sicuro che sia un'idea stupida, ma mi piacerebbe sapere perché, quindi abbi pazienza per un momento.
Gran parte del lavoro svolto dagli sviluppatori di backend consiste nel fornire accesso CRUD ai clienti tramite HTTP, essenzialmente dati di mappatura da e verso il database interno. I clienti autorizzano al servizio Web utilizzando una sorta di credenziali tramite una connessione crittografata, il servizio Web convalida i dati ed esegue query sul database back-end, quindi restituisce il risultato al client.

Tutto sommato, questo è semplicemente un modo peggiore per interagire direttamente con il database: quasi nessuno implementa completamente la specifica REST e prima o poi si finisce sempre con il filtraggio generico, l'ordinamento o l'impaginazione cucinati in casa - mentre SQL supporta già tutto questo.

Mi chiedevo: perché non dare ai clienti l'accesso al database esponendo la porta SQL, saltando completamente l'API HTTP? Questo ha molti vantaggi:

  • I client devono crittografare le connessioni utilizzando un certificato client
  • Possiamo utilizzare il controllo degli accessi integrato nel server o semplicemente utilizzare database shard per cliente
  • Le (mie-) autorizzazioni SQL sono piuttosto dettagliate, quindi scommetterei che non dovrebbero esserci problemi di sicurezza evidenti
  • Le prestazioni dovrebbero essere molto migliori, dato che saltiamo l'intero HTTP codice di comunicazione e web app
  • Le nuove funzionalità sono una questione di migrazione del database, tutto si riflette nello schema
  • Potenti funzionalità di query vengono fornite agli utenti, senza alcuno sforzo aggiuntivo

Gli svantaggi sembrano includere l'incapacità di supportare più versioni dello schema, anche se ritengo che deprecazioni accurate (e forse gli SDK client) dovrebbero ridurre al minimo l'impatto.

Poiché nessuno sembra farlo, deve esserci un rischio per la sicurezza che sto trascurando. Perché non possiamo fornire l'accesso SQL pubblico ai nostri clienti? Che cosa potrebbe andare storto? (Tieni presente che questo è solo un esperimento mentale nato dalla curiosità)

Non sono sicuro di aver capito la tua domanda, ma direi che è una questione di design.La tua idea potrebbe funzionare in alcuni casi semplici, ma in applicazioni più complesse diventerebbe presto un pasticcio (brutto o irrealizzabile).
Ciao Moritz.Ho modificato il titolo della tua domanda in modo che fosse una domanda reale.Se non ti piace la mia modifica, puoi ripristinarla o modificarla tu stesso!
Per riferimento, ci sono in realtà molti casi in cui le persone fanno esattamente questo, sebbene sia molto più comune nei vecchi software.Ci sono stati casi in cui ho dovuto aprire l'accesso diretto al database perché era l'unico tipo di integrazione supportato da alcuni software aziendali critici e meno recenti.Di solito in quel caso non darei l'accesso completo al database, né l'accesso alle tabelle utilizzate dalla mia applicazione.Invece ho mantenuto tabelle dedicate per il consumo dell'applicazione che si popolava solo quando avevo bisogno di inviare dati e altre tabelle da scrivere su cui controllavo regolarmente le modifiche.
In genere ciò veniva fatto tramite una connessione ODBC, quindi potrebbe valere la pena leggerlo (sebbene ironicamente lo stesso ODBC fosse effettivamente un livello di applicazione tra l'applicazione di integrazione e il database, è solo che ODBC interagirebbe direttamente con il database su Internet)
per i database che non dispongono di autorizzazioni a livello di riga, è possibile consentire loro di accedere solo alle viste che interrogano le righe che possono vedere in base alle loro credenziali
Penso che tu stia facendo una buona domanda.Quindi ottengo questo, utente SQL <-> https <-> (rest / api).Penso che il problema potrebbe essere che sql non ha la sicurezza.In questo modo il server web può parlare solo con il database non protetto.Questo potrebbe anche essere efficiente.
Inoltre non so quante iniezioni sql siano una cosa oggi, ma facendo in modo che il server web interroghi il database invece che il client, riduce la possibilità di comportamenti imprevisti, che sfruttano alcune vulnerabilità di sicurezza.Il resto api consente ancora un grande grado di programmabilità utente, ma rimuove la possibilità di iniezioni sql.Detto questo, ho visto js del sito Web che apparentemente ha formulato richieste sql.Alcuni siti memorizzano codice HTML e codice client su server sql, il che potrebbe essere guidato dal desiderio di ridurre i costi o la complessità forse?
In alcuni ambienti controllati e affidabili un approccio "valet key" consente l'accesso parziale / con ambito alle API.Azure Table, basato in parte su OData, CosmosDB e altri, lo supporta come alternativa alle chiamate OAuth da siti Web e app.
Considera anche CQRS al posto di CRUD.Sto perseguendo il CQRS a causa dei diversi effetti psicologici che ha quando parlo di dati.(Crud questo, rozzo quello .. porta con sé un peso inutile)
[GraphQL] (https://graphql.org/) risolve molti di questi problemi.
Perché non è mai CRUD, ecco perché.Con il tempo inizi a scrivere sempre più stored procedure e viste, il che diventa ingestibile, perché questo monolite dipende da RDBMS, che è ottimizzato per l'interrogazione e l'aggiornamento dei dati, ed è un cattivo sostituto per l'ecosistema di qualsiasi linguaggio principale (librerie, strumenti di sviluppo, vms, eccetera).
La migliore manutenibilità ottenuta utilizzando un livello di applicazione è di solito una ragione sufficiente.Tuttavia, è bene discutere anche degli aspetti di sicurezza.
Prima domanda: COME si connette il client al server che ospita il servizio di database Quel client avrà bisogno di un driver DBC installato sul proprio computer per effettuare la connessione. Client remoto che non può essere connesso tramite connessione tunneling, quindi la connessione NON può avere successo Un client remoto non può utilizzare il driver DBC su http (non compatibile) Giusto per reinterpretare: la sicurezza è la più grande preoccupazione in quanto protegge i dati. Le pratiche di ingegneria del software creano software di qualità, che protegge i dati. I dati sono il re! La qualità è regina! Il re ama la regina La regina ama il re
"" Le prestazioni dovrebbero essere molto migliori, dal momento che saltiamo l'intera comunicazione HTTP e il codice dell'app Web "" come sei arrivato a pensare che la comunicazione diretta nel database rimuove la comunicazione HTTP?Se si tratta di una sorta di database incorporato, la domanda non sarebbe ancora valida poiché si trattava di HTTP.
24 risposte:
#1
+138
ThoriumBR
2020-04-17 18:46:19 UTC
view on stackexchange narkive permalink

TL, DR: non farlo.

Le autorizzazioni (My-) SQL sono piuttosto dettagliate, quindi scommetto che non dovrebbero esserci qualsiasi ovvio problema di sicurezza

Anche con il permesso a livello di record, è facile scalare. Se un utente ha SELECT non limitato su una tabella, può selezionare qualsiasi record su quella tabella, anche quelli che non gli appartengono. Una tabella degli stipendi sarebbe pessima. Se un utente ha DELETE o UPDATE , potrebbe dimenticare la clausola WHERE e la tua tabella verrà visualizzata. Succede anche agli amministratori di database, quindi perché non dovrebbe accadere a un utente?

Le prestazioni dovrebbero essere molto migliori, dal momento che ignoriamo l'intera comunicazione HTTP e il codice dell'app Web

E butti via tutta la sicurezza, l'auditing, il filtraggio e il controllo dei permessi veramente fine dall'uso di un'applicazione per convalidare, filtrare, concedere e negare l'accesso. E di solito la maggior parte del tempo trascorso su una transazione è il database che elabora la query. Il codice dell'applicazione è inferiore e non rimuoverai la comunicazione HTTP, la sostituirai semplicemente con la comunicazione SQL.

Le nuove funzionalità sono una questione di migrazioni del database, tutto si riflette nello schema

Ecco perché così tante persone usano un "foglio di calcolo come database". Ed è un incubo quando è necessario riconciliare i dati da più origini.

Potenti funzionalità di query vengono fornite agli utenti, senza alcuno sforzo aggiuntivo

È come mettere un potente motore su uno scheletro telaio, imbullonare un sedile e portandolo a una gara. Non c'è peso extra che rallenti l'auto, quindi è molto veloce!

Qui è lo stesso. Certo, è veloce e potente, ma senza misure di sicurezza fornite dall'applicazione, nessuna sessione, controllo degli accessi a livello di record, "gli utenti fanno ciò che sono autorizzati a fare" o auditing.

Una delle vulnerabilità più comuni nelle applicazioni web è SQL Injection e stai fornendo una console SQL ai tuoi utenti. Stai dando loro un'ampia varietà di armi, molti proiettili e il tuo piede, la tua mano, la tua testa ... E ad alcuni di loro non piaci.

I commenti non sono per discussioni estese;questa conversazione è stata [spostata in chat] (https://chat.stackexchange.com/rooms/106981/discussion-on-answer-by-thoriumbr-why-cant-i-just-let-customers-connect-directl).
Sebbene la domanda sia contrassegnata con `mysql`, non sembra specifica per MySQL, quindi lasciami aggiungere alcune note.[PostgreSQL] (https://www.postgresql.org/docs/9.5/ddl-rowsecurity.html), [SQL Server] (https://www.mssqltips.com/sqlservertip/4028/sql-server-2016-row-level-security-example /) e [Oracle] (https://mwidlake.wordpress.com/2012/11/15/row-level-security-part-1/) hanno il livello di riga (a livello di record), quindi sembrano adattarsi molto meglio a questo tipo di attività.Anche [le viste possono essere usate] (https://stackoverflow.com/a/5527161/4862360) per quello con MySQL.
#2
+66
paj28
2020-04-17 19:11:44 UTC
view on stackexchange narkive permalink

Domanda interessante. In teoria, questo può essere fatto in modo sicuro. MS-SQL può proteggere la connessione con crittografia, autenticare l'utente e fornire autorizzazioni granulari e altre funzionalità di sicurezza come l'auditing.

In effetti, era comune negli ambienti intranet a cui avrebbero accesso i thick client un database direttamente, quindi i controlli di sicurezza del database erano il meccanismo di sicurezza principale. Questo tendeva a essere fatto male, ad esempio, tutti gli utenti si connettono come amministratori con una password codificata nell'app. Ma può essere fatto bene.

Uno dei problemi principali sono i difetti di escalation dei privilegi. L'API del database è estremamente complessa e presenta un'enorme superficie di attacco ei protocolli sono progettati per essere veloci, oltre ad essere vecchi e non protetti da Internet. Oracle, ad esempio, ha avuto centinaia di difetti di escalation dei privilegi. Tuttavia, MS-SQL è uno dei migliori database in questo senso. Puoi anche ridurre la superficie di attacco bloccando le autorizzazioni degli utenti.

Architettonicamente, esporre un'interfaccia che consente query generiche e applica restrizioni di sicurezza, ha molto senso. In una certa misura le persone stanno reinventando la ruota man mano che le API REST ottengono funzionalità come query personalizzate.

Se puoi farlo dipende in gran parte dal rapporto con i tuoi utenti. Se questi sono clienti paganti con un rapporto contrattuale, quindi in una certa misura più fidati di un utente Internet casuale, potrebbe essere appropriato utilizzare questa architettura. Soprattutto se client diversi sono inseriti in silos su database separati. Cammina con grande attenzione. È il genere di cose in cui se dovessi subire una violazione, potresti essere criticato per questo, nonostante abbia considerato attentamente i rischi e i benefici. Se stai eseguendo un servizio su scala web con iscrizione anonima, lo eviterei. Anche se vale la pena notare che la maggior parte dei fornitori di piattaforme cloud offre funzionalità in cui espongono le porte del database ai client.

Mi sono appena reso conto che hai detto che MySQL non è MS-SQL, ma la maggior parte di questo vale
Va notato che un'API può essere fornita avvolgendo le tabelle effettive in viste e utilizzando trigger di aggiornamento e stored procedure per gli aggiornamenti.In questo modo, se lo schema sottostante cambia, le definizioni possono essere aggiornate in modo che le vecchie query continuino a funzionare mentre vengono aggiunte nuove visualizzazioni che includono la nuova funzionalità.Se è meglio di un servizio separato sopra il database dipende dalla relativa complessità delle query e dalle operazioni di alto livello.
@JanHudec ma realisticamente, se dai agli utenti la possibilità di scrivere le proprie query, non hai alcuna possibilità di assicurarti che tutte le "vecchie query" funzionino, perché non hai idea di cosa siano.Le persone possono fare cose molto stupide.
@Nelson, se si concede agli utenti l'accesso solo alle * viste *, è possibile mantenere lo schema che vedono adattando la definizione delle viste a qualsiasi modifica nelle tabelle sottostanti che l'utente non vede.Inoltre, non è vero che non hai idea di quali siano le query, perché vedi quelle lente nel log delle query lente e puoi abilitare il log completo delle query se devi controllarle.
Dici che "era comune negli ambienti intranet".È il caso dell'ambiente intranet del mio datore di lavoro (ma certamente non di tutto ciò che è esposto a Internet).Questo (ora) è raro?Posso inviare query di sola lettura a quei database a cui mi è stato concesso l'accesso (database Oracle).
"L'enorme superficie di attacco" è ben strutturata.I canali per le infrastrutture critiche dovrebbero essere i più stretti e controllati possibile.
@gerrit - Non ho dati su questo.Informalmente è diventato meno comune.In parte perché i thick client possono utilizzare un back-end di servizi Web, Microsoft lo sta spingendo da 20 anni.Ma inoltre, le app interne ora sono spesso app web.Certamente si ottengono ancora alcuni thick client di database diretti.Ho cambiato lavoro alcuni anni fa, quindi non faccio test interni da 3 anni.
Quanto puoi fidarti * davvero * dei tuoi clienti, però?Anche se puoi fidarti di loro per non fotterti da soli, puoi fidarti di loro ** non ** per rendere la loro password "Password123"?O scriverlo su un adesivo se il sistema lo costringe a essere qualcosa di più complesso?Solo perché qualcuno accede come cliente fidato non significa che SIA quel cliente fidato.
@Steve-O - Questo è un buon punto!Un problema comune, non esclusivo di questo.In parte imponi alcuni minimi, come la forza della password o l'MFA.Non perfetto come fai notare.Quindi la cosa principale è imporre la separazione.Un cliente disattento può lasciarsi compromettere, ma non può influenzare gli altri clienti.Questo è esattamente ciò che fanno i fornitori di servizi cloud quando offrono DBaaS.Forse avrei dovuto dire "solo se silenziato" non particolarmente, ma lo lascerò.Angolo interessante, grazie.
#3
+56
NPSF3000
2020-04-18 02:39:36 UTC
view on stackexchange narkive permalink

Ho creato entrambe le interfacce REST e fornito ai clienti l'accesso diretto a SQL.

Il problema qui è che la domanda è fondamentalmente imperfetta:

Molto lavoro Gli sviluppatori di backend fanno è fornire l'accesso CRUD ai clienti tramite HTTP, essenzialmente mappando i dati da e verso il database interno.

Questa non è, nella mia esperienza, una parte significativa di ciò che faccio. Semplifichiamolo in 4 attività RE accesso ai dati:

  1. Convalida i dati in arrivo.
  2. Autenticazione, autorizzazione e registrazione.
  3. Esponi un insieme limitato di funzionalità.
  4. Fornisci un'API adatta all'utente.
  5. I database in genere non forniscono strumenti per eseguire questa operazione in base alle esigenze di queste attività. Ad esempio, potrei voler:

    1. Convalidare i dati in arrivo utilizzando un servizio esterno.
    2. Utilizzare OAuth per fornire l'autenticazione e ruoli per fornire l'accesso a righe specifiche. Ho quindi registri specifici che voglio scrivere in base a ruoli / accesso ai dati.
    3. Potrei voler esporre solo determinati rapporti (ad es. Per prestazioni (pensa DoS) o motivi di lavoro).
    4. SQL non è il formato che la maggior parte dei miei clienti desidera la maggior parte del tempo.

    Anche se sono sicuro che ci sia un database con alcune funzionalità per ciascuno di questi scenari ... in genere la maggior parte dei DB non supporta la maggior parte di questi scenari perché sono database e in quanto tali non progettati per gestire la logica aziendale.

    Tutto ciò detto, ci sono scenari in cui i client desiderano l'accesso a livello di database, nel qual caso troverai soluzioni che forniscono accesso diretto. Non c'è niente che vieti che ciò accada, semplicemente non è tipico.

Tutti i principali database dispongono di procedure memorizzate in cui è possibile programmare praticamente qualsiasi logica aziendale necessaria.Il vantaggio principale è che vengono eseguiti all'interno delle transazioni;fare transazioni su rest api tende ad essere brutto.Ma ovviamente sei ancora più limitato (solo PostgreSQL ha una scelta decente di linguaggi che puoi eseguire dalle procedure memorizzate).
@JanHudec Sebbene le stored procedure e le viste siano un buon complemento a un'applicazione, non sta sostituendo l'API REST con query SQL + stored procedure semplicemente spingendo il lavoro su un livello?Invece di scrivere endpoint REST per tutta la logica aziendale, si scrivono procedure memorizzate per tutta la logica aziendale.Ma ora i tuoi utenti possono anche eseguire qualsiasi query aggiuntiva che desiderano;query lente e bloccanti e whoops, qualcuno ha dimenticato una clausola where sul proprio aggiornamento.
@Schwern, no;il livello è definito dalla logica che contiene, quindi si tratta solo di implementare il livello utilizzando una tecnologia diversa.Non deve (deve) consentire all'utente alcuna query aggiuntiva o aggiornamenti rischiosi, perché gli si concede solo il permesso di leggere tramite viste, chiamare le procedure memorizzate e aggiornare anche tramite procedure memorizzate o viste con trigger di aggiornamento che implementano i controlli.Il livello dovrebbe ancora esistere, solo che ora è implementato nel motore di database anziché come servizio separato.Dipende da quale tipo di API è meglio esprimere le operazioni richieste.
@Schwern, e nota che le stored procedure sono assolutamente * orribili * per * integrare * un'applicazione, perché ora hai creato un livello aggiuntivo e distribuito la logica sui due livelli e il risultato è quasi certamente più difficile da mantenere.Metti tutta la logica nell'applicazione e hai un database stupido sotto il suo pieno controllo, oppure metti la logica nel database e accedilo direttamente (con un servizio leggero per cose che non possono eseguire SQL direttamente come le app web).
@JanHudec "Tutti i principali database dispongono di procedure memorizzate in cui è possibile programmare praticamente qualsiasi logica aziendale necessaria". Anche se * potresti * farlo, la domanda è se questo ha senso o meno per la tua applicazione.Ad esempio, molti backend contengono * più * diverse tecnologie di database, funzionano con vari servizi Web, utilizzano dozzine / centinaia di framework e librerie, a volte svolgono attività computazionalmente intensive e devono occuparsi del ridimensionamento.Non è necessariamente una questione di "può" ma di più "dovrebbe".
@NPSF3000, per alcune applicazioni ha senso, per altre no.Per le applicazioni che sono in gran parte centrate sui dati, spesso ha senso mettere una logica che garantisca la coerenza nel database e quindi i componenti che si occupano di varie parti del flusso di lavoro (report, importazioni, esportazioni ecc.) Si connettono in modo indipendente al database(ad esempio, lasciare che il cliente ne realizzi alcuni da solo).Per altri ha più senso avere un servizio di front-end che passa attraverso tutto il resto.Quindi sono d'accordo che è una questione di dovrebbe, ma ci sono casi in cui la risposta è sì.
@NPSF3000, i framework sono disponibili anche nei migliori motori di database.Postgresql consente fondamentalmente qualsiasi linguaggio principale, con qualsiasi libreria, per l'implementazione di stored procedure e il server IIRC ms sql consente tutto .net e Oracle consente tutto java.Il ridimensionamento è effettivamente più problematico, ma essere in grado di eseguire transazioni interne è un grande vantaggio per garantire coerenza.Quindi ci sono casi d'uso per entrambi gli approcci.
@JanHudec "Il ridimensionamento è davvero più problematico" Lo è di sicuro.Ad esempio, ho lavorato su sistemi che avevano * centinaia * di server che eseguivano il lavoro a livello di business, aumentando e diminuendo per gestire il carico.Ad esempio, ho avuto eventi in cui abbiamo * raddoppiato * il nostro carico di richieste elevate in pochi minuti.Come proveresti a progettarlo con Postgres?Perché dovresti provare? "ma essere in grado di eseguire transazioni interne è un grande vantaggio per garantire la coerenza." Non proprio ... potrei scrivere tutto il mio codice nelle transazioni oggi ... e non lo faccio - è una soluzione alla ricerca di un problema.
@NPSF3000, hai in mente un tipo specifico di applicazioni, una per la quale è sbagliato inserire la logica nelle stored procedure.Ma non tutte le applicazioni sono così.Un sistema in cui la funzione primaria è la contabilità (contabilità, ERP e simili) non ha bisogno di scalare, perché il numero di persone che lo utilizza è limitato, ma ha vincoli complessi e operazioni complesse (importa qualcosa, abbinalo a vari altri record e solo secorrisponde, commit) che sono più facilmente espressi utilizzando gli strumenti del database.Altrimenti finisci per racchiudere un mucchio di query come nella domanda.
@JanHudec certo, questo potrebbe essere un esempio in cui qualcuno vorrebbe utilizzare un database.
Cerchiamo di [continuare questa discussione in chat] (https://chat.stackexchange.com/rooms/106926/discussion-between-npsf3000-and-jan-hudec).
#4
+33
Lawnmower Man
2020-04-18 03:57:21 UTC
view on stackexchange narkive permalink

Prestazioni

Dici che le prestazioni dovrebbero essere "decisamente migliori", tranne per il fatto che ora hai appena dato agli attori malintenzionati l'autorità completa per distruggere le prestazioni del tuo DB. Ovviamente devono autenticarsi, ma l'attore "malizioso" potrebbe anche essere un utente legittimo "ingenuo e incompetente". Cosa farai quando gli utenti inizieranno a eseguire outer join su tutte le tabelle che possono trovare, con clausole where su ogni campo non indicizzato nel tuo DB e campi calcolati che sono computazionalmente costosi? A meno che il tuo DB non sia banalmente piccolo, sei esposto a questo rischio.

La mia ipotesi è che il tuo DB sia banalmente piccolo, perché una delle grandi cose che dovrebbe fare un'app web che fa da supporto a un DB è memorizzazione nella cache dei risultati più comuni . Non tutti i servizi possono farlo, perché alcuni sono progettati esplicitamente per fornire accesso in lettura / scrittura con piena coerenza. Ma molti sono di sola lettura e possono tollerare una certa latenza w.r.t. aggiornare la coerenza. Questi servizi possono essere letteralmente migliaia di volte più veloci dell'accesso diretto al database se utilizzano cache in memoria come mecached, redis, ecc.

Convalida

A meno che tu non abbia trigger di aggiornamento su ogni tabella che richiede un qualche tipo di convalida delle regole aziendali, l'accesso diretto è un buon modo per distruggere la tua integrità. Oh, è un campo codice postale in cui qualcuno ha appena scritto caratteri alfabetici? Nessun problema. Il campo del numero di telefono contiene alfa? Bene. Il campo valuta contiene virgole e punti e virgola? Forse qualcuno sta cercando di darsi un bonus gratuito con un po 'di hacking logico. Ti fidi davvero di OGNI SINGOLO UTENTE per eseguire lo stesso livello di convalida della tua webapp? Dovresti smettere di programmare e diventare un prete, perché il livello della tua fede è incredibile.

Manutenzione

A volte è necessario portare il database offline per eseguire una manutenzione importante. Una webapp di memorizzazione nella cache può almeno continuare a leggere il servizio mentre ciò accade, ma l'accesso diretto vince sull'intera comunità di utenti. A volte si desidera migrare il DB su un server più robusto. Cos'è quello? Hai problemi a convincere tutti i tuoi utenti a cambiare le loro stringhe di connessione allo stesso tempo? A volte vuoi passare al clustering. Oh, quelle stringhe di connessione hard-coded ti stanno davvero mordendo nel @ $$ ora, non è vero? La sicurezza ti ha appena chiesto di cambiare porta perché hanno aggiornato le regole del firewall? Hmm ... è ora di avvisare tutti i clienti che le loro stringhe di connessione devono essere aggiornate.

Conclusione

Se non intendi avere più di una manciata di clienti o più di un poche migliaia di righe e sei sicuro che il tuo DB / app non scalerà mai oltre questa dimensione del giocattolo, quindi l'accesso diretto è Just Fine (TM). Se, d'altra parte, il tuo DB potrebbe un giorno diventare troppo grande per la sua attuale incarnazione, o vuoi fare una migrazione importante che coinvolge la ristrutturazione, il ridimensionamento o il rehoming, allora ringrazierai le tue stelle fortunate che hai quello strato di indiretto da salvare la tua pancetta e porta tutta la bontà di una soluzione scalabile e ad alte prestazioni.

Sebbene non sia necessariamente il caso di un database di server tradizionale, se utilizzi uno dei database di big data SaaS come BigQuery o Aurora, quel problema di prestazioni dannose può trasformarsi in una capacità di far pagare ingenti fatture alla tua azienda molto rapidamente.Una volta mi sono imbattuto in una fattura inaspettata di $ 2000, perché il client interno era ingenuo riguardo alla memorizzazione dei dati in questione.Se fossero stati dannosi, avrebbero potuto accumulare $ 20-30.000 prima che ce ne accorgessimo.
@user1937198 per essere onesti, almeno per quanto riguarda BigQuery, puoi condividere i dati mentre consenti ai clienti di utilizzare i propri progetti di fatturazione per pagare l'utilizzo.BigQuery è un buon modo per condividere dati SQL su larga scala, ma per essere chiari è molto diverso da ciò che richiede OP.
Se lo imposti in questo modo.È meno comune pensarlo in un'azienda che non utilizza la fatturazione interna, ma dove il cliente interno è abbastanza lontano dagli operatori per non pensare ai costi
E dipende dalla struttura e dai meccanismi esatti dei prezzi.Ho più familiarità con AWS e so sicuramente che ci sono molti modi per spararti ai piedi con banconote secondarie come S3 lì.
Piccolo pignolo: non definirei tutti coloro che abusano del DB dannosi o incompetenti.Parte del punto nel separare gli sviluppatori front end e back end è che un frontender non * ha bisogno * di padroneggiare SQL o ricordare quali campi sono indicizzati (la maggior parte delle volte).Date loro le chiavi del DB e quello esce dalla finestra.
La memorizzazione nella cache è importante per noi.La nostra app è stata progettata per le LAN e si connette direttamente a un server SQL in sede e, anche con meno di 100 utenti alla volta, alcune delle query più grandi possono arrestare l'intero server quando 10 utenti le eseguono contemporaneamente.L'implementazione di un livello HTTP / SignalR ha portato a enormi miglioramenti delle prestazioni a causa della memorizzazione nella cache e non richiede al client di eseguire il polling per le modifiche.Non riesco nemmeno a immaginare di provare a ottimizzare per un servizio su scala web tutto con connessioni dirette.
#5
+19
poolie
2020-04-18 03:11:06 UTC
view on stackexchange narkive permalink

Questo potrebbe essere un approccio ragionevole in determinate circostanze:

  1. Il cliente ottiene l'accesso in sola lettura.

  2. Ottiene accesso in lettura a un intero database: si tratta di dati quasi pubblici per tutti i clienti o contiene solo i propri dati. In particolare, non deve contenere informazioni personali dell'utente o dati altrimenti soggetti a controlli normativi.

  3. Non ti dispiace che li leggano quanto vogliono o che ne facciano copie. Ad esempio, se perde e diventa completamente pubblico, non è altro che un po 'fastidioso.

  4. Non accedono al sistema di produzione live, ma piuttosto a un mirror write-behind o data warehouse.

  5. Hai adeguatamente considerato e affrontato il rischio di fuoriuscita di dati sensibili o specifici del cliente nel magazzino.

  6. Il sistema è tecnicamente isolato dai sistemi di produzione reali. Potrei forse creare un servizio Google BigQuery con un mirror dei tuoi dati e concedergli l'accesso.

  7. Hai a disposizione un buon modo per gestire le concessioni di accesso, inclusa la revoca, il rilevamento di abusi e consentire ai clienti di gestire la delega interna dell'accesso loro concesso. Ancora una volta, affidarlo a un provider IaaS come IAM di BQ è probabilmente molto più facile che presentarlo da soli.

  8. Il cliente desidera eseguire operazioni complesse su i dati che sono facilmente espressi in SQL e sanno come scrivere SQL.

  9. Il tuo schema esportato è abbastanza stabile, oi tuoi clienti sono abbastanza tolleranti, che la modifica dello schema e rompere le loro query non è un grosso problema.

Queste condizioni non sono totalmente in bianco e nero, ma l'accesso diretto a un database live contenente informazioni da molti utenti ottiene crescente rischioso nei modi descritti da altre risposte.

Uno scenario ipotetico in cui ciò potrebbe essere ragionevole è: hai un complesso catalogo di articoli in vendita. Le informazioni su quali parti hai e quali sono i loro prezzi non sono sensibili dal punto di vista commerciale e non sei troppo preoccupato che le persone ne tengano copie. Ed è più complesso di un semplice elenco: forse esistono relazioni complesse sui prezzi o su quali parti funzionano insieme.

Se si applicano tutte queste condizioni, il punto di partenza è fornire solo un download dei dati come CSV o JSON. Se non ti senti a tuo agio nel farlo, probabilmente neanche dare l'accesso a SQL è corretto. Tuttavia, ci sono un paio di casi in cui concedere l'accesso a BQ sarebbe meglio che fornire download:

  • Ci sono così tante tabelle che la gestione delle importazioni sarà fastidiosa per i clienti.

  • I dati sono molto grandi (TB?) e le query dell'utente ne leggono relativamente poco.

  • I dati vengono esportati frequentemente quindi, di nuovo , i download in batch saranno difficili da mantenere aggiornati.

  • Desideri fornire esempi predefiniti di query interessanti e controllare il motore delle query.

  • I tuoi clienti sono abbastanza tecnici per scrivere SQL ma non vogliono il fastidio di eseguire il proprio sistema di importazione e database.

  • Lo schema cambia abbastanza spesso che la loro importazione l'automazione si interromperebbe, ma non in modi che interrompono le loro query.


Un bell'esempio di questo modello è questo set di dati da 3 TB + da GitHub su BigQuery. Sebbene tutte queste informazioni siano disponibili tramite l'API GitHub, alcune query saranno molto più semplici o veloci in SQL. Altri set di dati includono pubblicità politica su Google e location di film a San Francisco.

Buona risposta.Descrive una serie di condizioni, che devono essere tutte soddisfatte, e se _tutte_ sono soddisfatte _poteva plausibilmente_ essere OK dare ad attori esterni un accesso relativamente diretto al database (sebbene possano esistere opzioni migliori come GraphQL).In tutte le altre situazioni non è una grande idea.
"Il cliente desidera eseguire operazioni complesse sui dati che possono essere facilmente espressi in SQL e sa come scrivere SQL".Questo è il primo punto a mio avviso: a meno che i tuoi utenti non siano utenti SQL avanzati, questo non funzionerà, e se lo sono, per cosa ti pagano comunque?
@Dragonel So come scrivere SQL ma pago (tantissime!) Aziende sia per l'accesso a dati ben curati, sia per beni e servizi a cui i dati sono accessori.
#6
+12
jl6
2020-04-18 13:52:26 UTC
view on stackexchange narkive permalink

Ecco un tipo di risposta bayesiano ...

Collettivamente, come settore, abbiamo circa tre decenni di esperienza nella progettazione di applicazioni a 3 livelli rivolte agli utenti e abbiamo accumulato una grande quantità di conoscenze su come fallo bene. Deviare da questo schema non è necessariamente sbagliato, come dimostrano alcune delle altre risposte, ma saresti in un territorio poco frequentato e correresti un rischio maggiore di commettere un errore fondamentale.

Da qui la domanda!Non presumo di essere più intelligente di tutti gli altri, ma vorrei capire perché questa non è una soluzione praticabile al problema.
Quando dici "tre livelli" cosa intendi esattamente?So che questo è un termine comune, ma le persone lo usano in modo diverso.
Presumo 1. Client 2. Server 3. DB
Disaccordo.L'industria è arrivata alla dottrina.Nessuna meritocrazia.Industria guidata fondamentalmente dalle bolle del credito.Differenza radicale nella cultura tra lo sviluppo web in alcuni settori e lo sviluppo in settori critici per la sicurezza, ad esempio sistemi di controllo, volo, spazio, militare, nucleare, ecc. L'architettura a 3 livelli non ha alcun vantaggio, merito.Solo dottrina arbitraria.
#7
+7
O. Jones
2020-04-18 18:10:44 UTC
view on stackexchange narkive permalink

tl; dr: non esporre il tuo DBMS alla rete pubblica, perché i cybercreep amano le grandi superfici di attacco.

Noi che gestiamo i sistemi informativi siamo in guerra con i cybercreep. Hanno tutti i vantaggi contro di noi: sono intelligenti, sono molto motivati ​​e hanno solo bisogno di trovare un buco nei nostri sistemi per picchiarci.

Stiamo difendendo i nostri sistemi. Dobbiamo tappare tutti i buchi . Un buon punto di partenza è limitare il numero di buche.

I server web sono buchi . È stato fatto ed è in corso un sacco di lavoro per limitare la superficie di attacco dei server Web esposti alle reti pubbliche. Quando i cybercreep escono con qualche nuovo exploit del server web, i fornitori in genere rilasciano rapidamente le patch. E queste patch non sono difficili da applicare prontamente.

Anche un DBMS pubblicamente esposto è un buco . Certo, alcuni di loro hanno un eccellente controllo dell'accesso con granularità per colonne, righe, visualizzazioni e tabelle. Quindi in teoria potrebbe essere possibile consentire l'accesso alla rete pubblica mantenendo la sicurezza.

Ma cosa succede se un cybercreep crea una sorta di exploit contro il DBMS?

  1. Essendo più complessi dei server web, i server DBMS hanno più possibilità di sovraccarico del buffer, escalation dei privilegi e altri exploit. Ogni minima funzionalità è un potenziale vettore di attacco.
  2. Vengono rilevati meno exploit DBMS (rispetto agli exploit del server web) perché la maggior parte dei DBMS si trova dietro i firewall.
  3. Se un cybercreep si intromette nel tuo DBMS, ha manipolato i tuoi dati e le tue applicazioni.
  4. Può essere davvero molto difficile applicare una patch a un server DBMS per collegare un buco.

Inoltre, se esponi il tuo DBMS a una rete pubblica, ai tuoi revisori della sicurezza non piacerà. Affatto. E per buone ragioni.

Per favore, non farlo.

#8
+7
fraxinus
2020-04-18 15:10:59 UTC
view on stackexchange narkive permalink

A volte è fatto. Esp. quando non ci sono opzioni migliori e in (un tentativo di) un ambiente abbastanza controllato. La percentuale di successo è bassa.

  1. RDBMS è in ritardo nella sicurezza rispetto ai server HTTP. Sono sviluppati e ottimizzati con diversi obiettivi in ​​mente. Il loro caso d'uso generale affronta un ambiente molto più amichevole rispetto al tipico server HTTP. Anche l'esposizione involontaria della porta del database in ascolto a Internet è considerata un errore di sicurezza.

  2. Il controllo dell'accesso a livello di riga è una cosa, ma raramente si adatta alla logica di business del database e più il database è normalizzato e più complesso è il tuo sistema di autorizzazione, meno si adatta. Ha anche implicazioni in qualche modo nascoste (dal punto di vista dello sviluppatore) sulle prestazioni.

  3. Interoperabilità: considerando il profondo disordine nei protocolli di accesso al database e nei relativi driver, preferisci non limitare i tuoi utenti a qualche stack o piattaforma di sviluppo. Tutti hanno a disposizione un client HTTP o SOAP, un client SQL a tua scelta: sei sicuro? Potresti anche pensare di cambiare il software del tuo database. Migrazione da Oracle a MySQL o aggiornamento atteso da tempo da PostgreSQL 9.2 a 12? Con l'interfaccia HTTP puoi farlo senza nemmeno informare i tuoi clienti. Dopo qualche tempo di inattività e pochi bug hai finito.

  4. Gli strumenti di sicurezza e gestione della rete (firewall, proxy, bilanciatori del carico, ecc ...) che lavorano su HTTP sono disponibili e diversi . Buona fortuna a trovare un sistema di rilevamento delle intrusioni che capisca il protocollo TDS.

#9
+5
elsadek
2020-04-18 04:58:58 UTC
view on stackexchange narkive permalink

Poiché nessuno sembra farlo, deve esserci un rischio per la sicurezza che sto trascurando.

Errore umano, concessione dell'autorizzazione sbagliata a un client a livello di database , potrebbe avere conseguenze drastiche.

Perché non possiamo fornire l'accesso SQL pubblico ai nostri clienti? Cosa potrebbe andare storto?

Stai creando inutili inconvenienti per il sistema del tuo cliente:
- Per scrivere le query sql corrette sul tuo database, il tuo cliente deve capire il tuo schema del database o ne ha bisogno solo una parte?
- Il codice del cliente sarà strettamente associato al database, qualsiasi modifica allo schema deve riflettersi sul codice del cliente.

Ecco perché, dall'anno 1, tendiamo a scrivere applicazioni ed endpoint API per astrarre le strutture dei database.

#10
+5
lights0123
2020-04-18 07:57:47 UTC
view on stackexchange narkive permalink

Una cosa simile viene effettivamente eseguita con programmi come Hasura: quel programma espone il tuo database, utilizzando il sistema di permessi di PostgreSQL per i permessi a livello di riga e di colonna, su un'interfaccia GraphQL. I client non ottengono la piena potenza delle query SQL, ma ottengono un sottoinsieme tramite query GraphQL. Ciò consente query che ottengono un sottoinsieme di dati (invece di ogni colonna), nonché join e un certo livello di filtraggio. La piena potenza di SQL non è completamente esposta, il che significa che non è possibile creare una query che crei un attacco DOS contro il server. Ogni query viene trasformata in una query SQL, limitando al contempo l'accesso a funzionalità che potrebbero rallentare il server.

Per quanto riguarda le migrazioni, sei sicuramente in grado di aggiornare l'API semplicemente migrando il database. Se è indesiderato, Hasura ti consente di utilizzare viste SQL personalizzate che traducono le tue tabelle effettive in tabelle rivolte al pubblico, in modo da poter modificare la rappresentazione interna senza influire sull'API. Inoltre, puoi sempre sostituire Hasura con qualsiasi altro server che espone semplicemente la stessa API, quindi non sei bloccato.

Tuttavia, hai ancora il sovraccarico di HTTP, ma puoi anche utilizzare il Interfaccia WebSocket per evitare di riconnettersi ogni volta.

È davvero interessante, guarderò Hasura per alcuni dei miei progetti.
GraphQL è un'opzione eccellente per fornire uno strato di mediazione tra A) ciò che si desidera esporre e un "modello logico" per esso, e B) il proprio backend effettivo.
Quando parliamo non solo di SQL, mi chiedo che nessuno abbia menzionato FaunaDB o Firebase che fanno esattamente ciò che è in questione.
@Mišo tranne che stiamo parlando di SQL.GraphQL può offrire un'astrazione su SQL, ma da qualche parte c'è ancora un database SQL.E mi sembra strano avere un database che non puoi nemmeno ospitare da solo.
@lights0123, puoi aggiungere qualsiasi astrazione su SQL.C'è anche un progetto http://postgrest.org/ per fornire l'API REST.Ma personalmente non penso che sia davvero importante quale tecnologia viene utilizzata per l'archiviazione dei dati sotto il cofano fintanto che fornisce un linguaggio di query come SQL, GraphQL (https://fauna.com), REST, ... (https://firebase.google.com/products/realtime-database)
#11
+4
Gaius
2020-04-18 19:43:03 UTC
view on stackexchange narkive permalink

Fai la domanda

Perché non posso semplicemente consentire ai clienti di connettersi direttamente al mio database?

E la risposta dipende davvero da chi sei significa clienti in questo contesto. Persone a caso su Internet? Come la maggior parte delle altre risposte hanno detto, questa è una cattiva idea e hanno fornito molte buone ragioni. Ma se i tuoi clienti sono partner commerciali affidabili, ad es. B2B e hai connessioni VPN tra i tuoi siti e forse anche una soluzione SSO federata, quindi questa non è automaticamente una cattiva idea. Sarà un incubo di supporto, tuttavia, a meno che non sia incredibilmente ben documentato, passerai tutte le tue giornate a rispondere a domande su quali dati sono presenti in ciascuna tabella.

nessuno sembra farlo

Potresti essere sorpreso.

Sono d'accordo con te che l'autore non è riuscito a definire il proprio cliente.Aggiungere alla tua risposta quanto sia intuitivo il tuo sistema potrebbe essere un fattore da considerare.
#12
+3
Vilx-
2020-04-19 04:59:15 UTC
view on stackexchange narkive permalink

Anche nell'RDBMS più avanzato che ho visto, non puoi ottenere una sicurezza abbastanza buona fuori dalla scatola. Le regole aziendali per tutte le applicazioni tranne le più banali sono semplicemente troppo complesse. Devi scrivere codice personalizzato che limiti ciò che possono fare in modi specifici se non vuoi che gli hacker malvagi causino il caos. Ora, potresti inserire tutto in stored procedure e consentire solo ai tuoi clienti di chiamarle ... ma poi sei tornato dove hai iniziato: hai ancora un'app personalizzata su un database di base . E il linguaggio della procedura memorizzata è solitamente molto più scomodo e difficile da usare rispetto ai tuoi linguaggi di programmazione generici (PHP / C # / Java / Javascript / Ruby / Python / ecc.)

Esattamente.Gli strumenti di ingegneria del software - IDE, debugger, framework, librerie, gestione degli errori, registrazione, prestazioni e profilazione - sono migliori di almeno due ordini di grandezza per i linguaggi applicativi (Java, C #, Node JS) rispetto alle stored procedure / codice di database incorporato.
#13
+2
jmoreno
2020-04-19 04:24:06 UTC
view on stackexchange narkive permalink

Il tuo terzo punto elenco, in realtà, deve essere il tuo primo, poiché è il motivo più importante per non consentire l'accesso diretto.

  • Le autorizzazioni (My-) SQL sono carine a grana fine, quindi scommetto che non dovrebbero esserci problemi di sicurezza evidenti

Il motivo principale per cui ciò non è fatto è perché la sicurezza a livello di riga non è stata una cosa per così tanto tempo e senza sicurezza a livello di riga non c'è sicurezza nel tuo scenario. MySQL non ha ancora la sicurezza a livello di riga.

E la sicurezza a livello di riga non pone fine ai tuoi problemi di sicurezza e progettazione, è solo un primo passo necessario. Fondamentalmente, non ci sono vantaggi che superino il problema della sicurezza.

Che è prevedibile. Descriverei un database con tra 50 e 500 tabelle come leggermente complesso. Anche se le persone fossero oneste al 100%, non vorrei che usassero il database per interazione diretta.

Credo che nella maggior parte delle organizzazioni, se qualcosa può essere fatto tramite l'applicazione, è considerato meglio farlo in questo modo che attraverso l'accesso diretto al database, anche se l'utente ha la capacità e la conoscenza per farlo attraverso il database.

La capacità di tenere gli utenti fuori dal database e richiedere loro di apportare le modifiche in modo definito è uno dei motivi per allontanarsi da Access e / o Excel. Espandilo da un'organizzazione in cui puoi almeno supporre che tutti gli utenti siano affidabili se non ugualmente competenti, a Internet più ampio in cui dovresti davvero presumere che qualsiasi utente casuale sia un cattivo attore ...

#14
+2
Brian B
2020-04-19 04:45:08 UTC
view on stackexchange narkive permalink

Sembra che tu abbia una situazione in cui non sei troppo preoccupato per quali client vedono quali righe di dati, o per i client che devono aggiornare piuttosto che solo interrogare le tabelle.

Un'alternativa che potrebbe adattarsi al tuo utilizzo il caso è semplicemente fornire, direttamente o indirettamente, una copia del database ai clienti. Immagina di inviare loro un clone di SQLite come file, all'interno di un'applicazione o anche direttamente, a seconda della loro sofisticazione. Questo aggira i problemi di prestazioni in caso di query non corrette, almeno per i tuoi server.

In questa epoca moderna in cui le persone guardano video di YouTube di dimensioni gigabyte, puoi permetterti di inviare un database piuttosto grande attraverso il cavo nel suo interezza.

#15
+2
Sergey Shcherbakov
2020-04-18 13:48:05 UTC
view on stackexchange narkive permalink

Se dai un'occhiata a come viene eseguita l'API di Elasticsearch, probabilmente troverai una somiglianza con la tua idea. Avere solo Elasticsearch ti evita di sviluppare qualsiasi codice di backend personalizzato e costruire la tua API REST se il tuo caso è semplice. client direttamente all'API REST di Elasticsearch e il gioco è fatto. (Non è che io stia sostenendo Elasticsearch. Trovo solo che questo sia un buon esempio del mondo reale per la tua idea)

#16
+2
New Alexandria
2020-04-19 09:27:19 UTC
view on stackexchange narkive permalink

Ciò è possibile a condizione di selezionare il servizio di database corretto. La realtà è che sono pochi quelli che forniscono un misto di granularità dei permessi e modello di accesso. Senza cercare di promuovere i prodotti, ma ad esempio oggi, puoi ottenere risultati simili con sistemi di database "su scala aziendale" come

  • DB2
  • Snowflake
  • Oracle
  • MSSQL

e probabilmente altri.

La sfida è che questi sistemi sono piuttosto complicati da gestire. Se

  1. hai il team,
  2. puoi supportare & permettersi il sovraccarico operativo e
  3. puoi vendere il prodotto dati in questo modo,

allora chi ti fermerà?

Ciò che di solito li ferma è

  1. che più talenti là fuori costruiscono app. Le app possono anche essere la loro crescita professionale preferita, non sono rari gli sviluppatori di configurazione DB
  2. Testare questi sistemi per il controllo di qualità è diverso dai metodi per le app. Gestire per questo potrebbe richiedere più tempo o incorrere nelle stesse sfide di talento.
  3. I team di vendita spesso non sono così esperti di tecnologia, ma gli ingegneri delle soluzioni sì. La maggior parte degli ingegneri delle soluzioni controparti non sono amministratori di database. Ciò aumenta l'attrito nelle vendite. La gente compra cose che hanno senso per loro.

Procedi con leggerezza. Innovare. Pianifica bene.

#17
+1
Steve Morrison
2020-04-19 02:54:06 UTC
view on stackexchange narkive permalink

Ci sono pro e contro, ma SE hai intenzione di esporre il database al tuo client, rendilo una piccola superficie di attacco dando loro solo l'accesso a un particolare schema. Questo schema conterrà solo stored procedure che consentirai loro di eseguire. Questo mitigherà gli attacchi SQL injection, l'autorizzazione di cui l'utente dispone dipende dall'autorizzazione SQL.

Se desideri che clienti diversi siano in grado di accedere solo ai propri record e abbiano autorizzazioni diverse per persone diverse nella stessa organizzazione cliente, puoi fare tutto questo all'interno di stored procedure sempre più grandi. In sostanza, stai costruendo la tua API all'interno della stored procedure e, se stai per farlo, è meglio per quanto riguarda la manutenibilità, avendo il tuo livello API nel livello intermedio. Se si dispone di una logica aziendale complessa, sia in termini di prestazioni che di manutenzione, è meglio in un livello intermedio che in una stored procedure.

Quindi, in sintesi, è possibile inserire tutto nel database SQL e nelle stored procedure se lo desidera. Sia dal punto di vista funzionale che di sicurezza, puoi farlo funzionare con una piccola superficie di attacco. Ma se hai un sistema complesso e capisci di cosa si tratta, la maggior parte delle volte non vorrai.

#18
+1
Thomas W
2020-04-20 03:59:04 UTC
view on stackexchange narkive permalink

I server delle applicazioni (server web, contenitori ecc.) dovrebbero essere esposti direttamente a clienti / attori esterni non attendibili e sottoposti a test di sicurezza molto più severi per questo scopo. I server di database, a confronto, hanno spesso vulnerabilità rilevate e, se esposti direttamente, sarebbero probabilmente soggetti a exploit.

Logica dell'applicazione L'autorizzazione di & può spesso essere non banale. Sebbene i sistemi di database offrano alcune funzionalità limitate, sarebbe probabilmente più coeso centralizzarle in un sistema più capace (logica dell'applicazione).

Disaccoppiamento

Consentire ai clienti di accoppiarsi direttamente al tuo modello di dati fisico, causa un problema in quanto diventi contrattualmente / commercialmente obbligato a mantenere esattamente lo stesso modello di dati. Questo è molto indesiderabile, poiché rende impossibile mantenere / migliorare / rifattorizzare il tuo modello di dati poiché cambiarlo danneggerà i clienti. (La direzione ti dirà di non farlo.)

Questo è particolarmente negativo se non riesci a vedere come lo stanno utilizzando i tuoi clienti, ad es. se gli dai una connessione DB non elaborata, & non può nemmeno analizzare / riscrivere ciò che stanno facendo.

Anche la portabilità tra i backend è un problema. Sebbene la sicurezza e le funzionalità di proc / scripting memorizzate offerte dal DB siano strumenti limitati e scadenti per il lavoro, peggio ancora sono specifici del fornitore. Quando desideri migrare a un database diverso per motivi di prestazioni / scalabilità / costo, ti ritroverai bloccato.

La soluzione preferita è quella di contrarre un "modello logico", che è in qualche modo disaccoppiato dal tuo fisico implementazione. Questo ha anche il vantaggio di fornire generalmente un modello più semplice, più chiaro e più utile per le parti esterne.

Migliore struttura API

Diversi potenziali miglioramenti:

  1. Come accennato, la definizione di un bel modello logico chiaro è normalmente più facile da consumare per i tuoi clienti.
  2. Offrirlo da REST lo rende molto più ampiamente disponibile, da una vasta gamma di strumenti software client &, che richiedere al software client di includere una libreria DB specifica, aprire una connessione & eseguire SQL.
  3. API standard come GraphQL possono fornire a & un accesso simultaneo potente e generalizzato ai grafici e il recupero dei dati attraverso il tuo modello logico , ad es. molti dei vantaggi di SQL, fornendo un migliore grado di autorizzazione e controllo.

Efficacia dello sviluppo

Strumenti di ingegneria del software - IDE, debugger, framework, librerie, gestione degli errori, registrazione, prestazioni e profilazione - sono probabilmente due ordini di grandezza migliori per i linguaggi applicativi (Java, C # .. anche altri lang come Node JS, Rust, Go) rispetto alle stored procedure & codice del database incorporato.

Dato che i costi di manutenzione a vita sono 4-10 volte quelli dello sviluppo iniziale, anche un progetto iniziale "molto piccolo" di diciamo 7 giorni di esposizione dei dati ai clienti rischia di incorrere in grandi differenze di costo di vita.

Dal punto di vista dello sviluppo, mi aspetterei una differenza di produttività 3-4 volte superiore per utilizzare strumenti ragionevoli del linguaggio applicativo & un framework moderno (Spring Boot, GraphQL o simili). Dal lato del cliente mi aspetto che le cose siano molto più facili da consumare i dati & molto meno interruzioni (poiché l'API sarà in grado di essere stabile).

Coloro che sostengono che non ci sarebbero costi sul lato di sviluppo per expose SQL sta probabilmente omettendo il costo del tentativo di implementare le regole di sicurezza, tentando di correggere i problemi del modello di dati e cercando di risolvere i problemi di sicurezza a posteriori.

Quanto costerà scrivere un proxy di connessione DB personalizzato per leggere il protocollo wire del database, analizzare le query SQL e bloccare i problemi di sicurezza a livello di query SQL? Perché se consenti un raw La connessione SQL e le regole DB sono inadeguate (cosa che sappiamo praticamente essere), questo è il tuo fallback di sicurezza.

Raccomandazioni

Fai da te e un favore ai tuoi clienti. GraphQL potrebbe o non potrebbe essere adatto a te, ma offre molti dei vantaggi di SQL mentre aggira molti dei problemi.

Usa un linguaggio applicativo moderno: framework &: preferisco Java (SpringBoot) o C #, ma sono disponibili altre opzioni come NodeJS ecc. (Evita PHP).

Suggerirei:

  1. Collega un framework GraphQL, crea un modello logico, prova GraphQL.
  2. In alternativa, crea creare un'API REST per ogni vista ben definita, implementando la logica di autorizzazione nell'applicazione, rispondendo a JSON se possibile - magari aggiungi un'opzione CSV se i tuoi clienti vogliono davvero dati flat.

Spero che questo aiuta!

#19
+1
Billy
2020-04-19 23:40:59 UTC
view on stackexchange narkive permalink

Perché non posso semplicemente consentire ai clienti di connettersi direttamente al mio database? Perché non concedere ai clienti l'accesso al database esponendo la porta SQL, saltando completamente l'API HTTP?

Non puoi / non dovresti perché il controllo degli accessi fornito dal tuo motore di database probabilmente manca della granularità necessaria per controllare adeguatamente l'accesso del tuo cliente.

La maggior parte dei database è normalizzata e questo si traduce in tutti gli oggetti dello stesso tipo archiviati nella stessa tabella. Anche quelli che appartengono a clienti diversi.

La maggior parte (tutti) i sistemi di autorizzazione dei motori di database concedono o negano l'accesso a intere tabelle contemporaneamente, non su base record per record. E probabilmente non vuoi che un cliente veda i dati di tutti gli altri clienti .

Ecco perché vale la pena scrivere un gestore API che esegua le query sul database per conto del cliente, e restituisce solo i risultati che un determinato cliente è autorizzato a ricevere. L'API può anche implementare la fatturazione, la limitazione della velocità, la registrazione e altre utili funzioni aziendali che il motore di database non può.

Quindi sì, potresti concedere l'accesso diretto al database e la configurazione una stored procedure notturna che scaricherà tutti i dati di cui un cliente avrebbe bisogno in una tabella e gli darebbe accesso solo a quella tabella. Ma non è consuetudine creare una tabella per ogni cliente e va contro la normalizzazione. Introdurrebbe un ritardo nella visualizzazione di nuovi dati da parte dei clienti, un picco ricorrente di IO per rigenerare le tabelle visualizzabili dai clienti e utilizzare molto più spazio su disco.

Non fornire ai clienti l'accesso SQL diretto al database.

#20
  0
usr-local-ΕΨΗΕΛΩΝ
2020-04-20 14:33:04 UTC
view on stackexchange narkive permalink

Non lo metterei sulla prospettiva della sicurezza , piuttosto sull'ingegneria del software

Perché non dare ai clienti l'accesso diretto al CRUD?

Perché le primitive CRUD (Crea, Leggi, Aggiorna, Elimina) sono primitive atomiche . Non implementano la logica di business. E i modelli di autorizzazione relazionale non tengono conto della segregazione dei dati

Supponendo che la sicurezza sia ben definita, ecco alcuni motivi per cui CRUD non funziona

CRUD è atomico. Troppo atomico per gli affari

Un trasferimento di denaro è costituito da un credito e da un debito. Due domande. Sei sicuro al 100% che i tuoi clienti eseguiranno tutte le query nell'ordine previsto e all'interno di una transazione? Il tuo database relazionale non applica il vincolo newtoniano che "il denaro non può essere creato o distrutto, ma solo trasferito".

Un'API REST garantisce di eseguire due query in una transazione.

I permessi sono limitati

I permessi relazionali non tengono conto della semantica dei dati e della logica di business. Se hai accesso a UPDATE (diciamo che non hai accesso a DELETE per motivi di discussione) non puoi (facilmente) limitare i valori che il tuo cliente vuole scrivere.

E se AGGIORNI il numero di coupon su un account quando effettivamente non hai così tanti coupon disponibili nella tua azienda?

Un'API REST convaliderà i dati in input prima di inviare query

Le autorizzazioni don non consentire la segregazione

Normalmente discriminerai gli inquilini in base a un valore di colonna (ad esempio TENANT_ID). L'accesso READ garantisce l'accesso a ogni informazione.

Le autorizzazioni SQL consentono di limitare le colonne disponibili a un determinato ruolo, NON le righe.

Un'API REST aggiungerà un filtro a ogni query

Controllo e registrazione

Con l'accesso diretto a CRUD ti affiderai ai clienti che emettono un INSERT INTO AUDIT_LOG . Malizia a parte, sei sicuro che tutti emetteranno quella domanda? Con vincoli di budget, mi aspetto che qualche cliente "dimentichi" di implementare quella query e dimentichi di testare.

Un'API REST emetterà log di controllo ad ogni chiamata.

In breve

Dare l'accesso CRUD agli utenti dei clienti è troppo primitivo e consente a una miriade di utenti lo stesso livello di MALE garantito dall'accesso a fogli Excel di un ordine sulla stessa cartella NAS.

Fidati di me, Ho assistito a recuperi in caso di disastro che voi umani ...

#21
  0
jo0gbe4bstjb
2020-04-19 21:21:23 UTC
view on stackexchange narkive permalink

In alternativa, puoi stabilire una connessione tramite una VPN affidabile. Tuttavia, in termini di sicurezza del server di database, è necessario configurare autorizzazioni più sicure e diritti di accesso ristretti per gli utenti che appartengono allo schema del database del client sul server del database.

Ma questo non è raccomandato per i client pubblici, di solito solo per topologia interna.

#22
  0
Jasen
2020-04-19 09:01:40 UTC
view on stackexchange narkive permalink

Fintanto che non concedi loro l'accesso in scrittura ai dati che non dovrebbero essere autorizzati a modificare o l'accesso in lettura ai dati che non dovrebbero essere in grado di leggere, questo sembra accettabile.

Molti sistemi inseriscono i dati appartenenti a clienti diversi in una tabella condivisa, questo ovviamente sarebbe un approccio inadatto.

#23
-1
Ariff
2020-04-17 18:38:42 UTC
view on stackexchange narkive permalink

Quando si accede direttamente al DB, si perde il controllo sul tipo di istruzioni CRUD che vengono emesse. Un utente malintenzionato può emettere un'istruzione come delete da table_name e tutti i tuoi dati andrebbero persi.

Dal punto di vista della "cordialità" dell'utente, un'API sarebbe molto più semplice e diretta rispetto all'emissione di istruzioni SQL in cui l'utente finale molto probabilmente ora conoscerà il design del DB.

Considera però che non hanno il privilegio di eliminare tabelle o eliminare dati da tabelle che non appartengono al loro account.Questo è qualcosa che MySQL supporta in modo nativo, ad esempio. E la prospettiva della "cordialità" è duplice: gli sviluppatori Web potrebbero essere più abituati a JSON tramite HTTP, mentre gli analisti di dati preferiscono fortemente SQL se gli viene data la scelta.
Accetterò la risposta di Ariff come un chiaro esempio di autorizzazione dell'applicazione.Le _Applicazioni_ sono generalmente un luogo migliore per implementare la logica dell'applicazione, il controllo delle autorizzazioni dell'applicazione e le API dell'applicazione.Alcune parti semplicistiche di questi (non tutti) possono essere teoricamente implementate nello scripting di database, l'efficienza di sviluppo e l'efficacia di questi strumenti sono molto inferiori.C'è una ragione per cui _application_ è una parola separata da _database_.
#24
-2
Anonymous
2020-04-17 19:50:09 UTC
view on stackexchange narkive permalink

Ecco perché abbiamo software di business intelligence come Business Objects e altri: per consentire agli utenti di creare le proprie query senza padroneggiare SQL e anche limitare ciò che possono vedere. Ovviamente le autorizzazioni possono essere impostate per utente.

Per darti un'idea, un'azienda con cui lavoro fornisce accesso remoto ai dati tramite SAP Business Objects. Gli utenti hanno accesso a una serie di rapporti già pronti e non sono autorizzati a crearne di propri (questo è per impostazione predefinita). Ricevono anche alcuni file Excel ogni giorno (o settimana), generati da BO. Sono abbastanza contenti di questo, perché stiamo facendo il loro lavoro, o la maggior parte di esso. Un criterio importante è: i tuoi clienti hanno bisogno di dati in tempo reale o meno. In caso contrario, puoi fornire i dati in modo controllato come un download CSV .

Esporre il tuo database non sembra essere una buona idea a prima vista. Ho notato che dici clienti e non sviluppatori , ovvero persone che sviluppano effettivamente attorno ai tuoi sistemi e necessitano dell'accesso remoto per un motivo valido. Non credo che ai non sviluppatori debba essere concesso un livello di accesso così ampio.

I tuoi clienti potrebbero non essere abbastanza dannosi o tecnicamente competenti per fare confusione con il tuo sistema, ma c'è sempre la possibilità che uno di loro sta lavorando da un computer compromesso (ancora troppe persone eseguono software crackati o scaricano applicazioni dubbie ...). In un certo senso, gli utenti innocenti potrebbero essere più pericolosi degli esperti IT, perché la loro posizione di sicurezza tende ad essere piuttosto debole.

C'è anche la questione della responsabilità se un si verifica una fuga , in particolare una fuga di dati personali. La tua azienda potrebbe essere soggetta a un regime normativo come il GDPR e passibile di multe salate per la mancata protezione adeguata dei tuoi dati.

Non stai pensando fuori dagli schemi come farebbe un hacker (o un penetration tester). Le autorizzazioni granulari sono il minimo, ma l'ambito della tua sicurezza va oltre Mysql. Puoi scrivere file usando MySQL, ovviamente non in una posizione arbitraria, ma dipende dalle tue impostazioni. Se Mysql è configurato in modo errato (ad es. In esecuzione come root) o hai autorizzazioni eccessive su alcune cartelle, allora c'è un po 'di spazio per i compromessi.

Leggi anche file da Mysql, ad esempio:

  select load_file ('/ etc / passwd') 

La risposta ovvia qui è negare il privilegio FILE . Ma sei sicuro di aver considerato ogni possibile scenario? E sei disposto a mettere in gioco il tuo lavoro se le cose vanno male e sei incolpato per l'incidente? (Credo nella legge di Murphy).

Poiché nessuno sembra farlo, deve esserci un rischio per la sicurezza che sto trascurando. Perché non possiamo fornire l'accesso SQL pubblico ai nostri clienti? Che cosa potrebbe andare storto? (Tieni presente che questo è solo un esperimento mentale nato dalla curiosità)

Scenario peggiore: il tuo server di database è compromesso, quindi un hacker usa il server come gateway per il resto della rete aziendale. Questo è ciò che accade ogni giorno nel mondo reale: una singola macchina viene hackerata, una workstation o un server esposto su Internet. Spesso inizia con una SQL injection o qualche vulnerabilità comune, o semplicemente un exploit che sfrutta il software senza patch (Think Equifax). Quando gli hacker prendono piede sulla macchina, si inseriscono nella tua rete e cosa troveranno?

Riconsidererei seriamente l'idea, ma qualunque cosa tu faccia registra tutto .

Penso che questa sia per lo più una buona risposta, ma voglio mettere in dubbio alcuni punti: 1) Per cose come i download CSV questi hanno bisogno di sviluppo, che è ciò che OP stava cercando di evitare.2) Questo sposta la responsabilità del GDPR solo se si tratta di una decisione tecnica sbagliata, che è esattamente la domanda che viene posta.3) Per impostazione predefinita, i normali utenti MySQL non hanno il permesso FILE, quindi questo dovrebbe essere concesso per errore, non solo dimenticato.4) È standard inserire i sistemi rivolti al cliente in una DMZ per evitare il pivot della rete.Ci scusiamo per tutti i pignoli, volevo solo concentrarmi sui fatti.
Sono d'accordo con te _per la maggior parte_, ma in realtà sto pensando più fuori dagli schemi di te :) La domanda è mantenuta intenzionalmente ampia, dal momento che non volevo concentrarmi sull'implementazione.Pensa di fornire l'accesso a una replica di lettura frammentata che contiene solo dati specifici del cliente, ad esempio, in esecuzione nella propria DMZ.Forse anche avere un server di backend che parla semplicemente un sottoinsieme di SQL e applica le proprie restrizioni.Ci sono un sacco di possibilità in questo spazio problematico e sono solo curioso.Nessun server di database è stato danneggiato nella realizzazione di questa domanda;)


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 4.0 con cui è distribuito.
Loading...