Domanda:
Perché le stored procedure e le istruzioni preparate sono i metodi moderni preferiti per prevenire SQL injection rispetto alla funzione stringa () di escape reale di mysql
Damien Pham
2020-04-21 06:45:59 UTC
view on stackexchange narkive permalink

Perché le stored procedure e le istruzioni preparate sono i metodi moderni preferiti per prevenire l'iniezione di SQL tramite la funzione mysql_real_escape_string () ?

I commenti non sono per discussioni estese;questa conversazione è stata [spostata in chat] (https://chat.stackexchange.com/rooms/107110/discussion-on-question-by-damien-pham-why-are-stored-procedures-and-prepared-sta).
Dodici risposte:
#1
+67
multithr3at3d
2020-04-21 07:58:19 UTC
view on stackexchange narkive permalink

Il problema dell'SQL injection è essenzialmente la combinazione di logica e dati, dove ciò che dovrebbe essere dato viene trattato come logica. Le istruzioni preparate e le query parametrizzate risolvono effettivamente questo problema all'origine separando completamente la logica dai dati, quindi l'iniezione diventa quasi impossibile. La funzione di escape della stringa in realtà non risolve il problema, ma cerca di evitare danni facendo l'escape di determinati caratteri. Con una funzione di escape di stringa, non importa quanto sia buona, c'è sempre la preoccupazione di un possibile edge case che potrebbe consentire a un carattere senza escape di sopravvivere.

Un altro punto importante, come menzionato in @ Sebastian's commento, è che è molto più facile essere coerenti quando si scrive un'applicazione utilizzando istruzioni preparate. L'uso di affermazioni preparate è architettonicamente diverso dal semplice vecchio modo; invece della concatenazione di stringhe, si creano istruzioni associando parametri (ad esempio PDOStatement :: bindParam per PHP), seguite da un'istruzione di esecuzione separata (PDOStatement :: execute). Ma con mysql_real_escape_string () , oltre a eseguire la query, devi ricordarti di chiamare prima quella funzione. Se la tua applicazione ha 1000 endpoint che eseguono query SQL ma dimentichi di chiamare mysql_real_escape_string () anche solo su uno di essi, o lo fai in modo improprio, l'intero database potrebbe essere lasciato completamente aperto.

Infatti.Anche senza preoccuparsi di SQLi, le query preparate rappresentano una corretta separazione delle preoccupazioni.
L'altro punto è che tutto ciò che serve è dimenticare di chiamare `mysql_real_escape_string ()` una volta, e il tuo DB è completamente aperto.Usare sprocs e dichiarazioni preparate di solito è architettonicamente una proposta tutto o niente - o lo fai ovunque o da nessuna parte.
Ma questo è anche uno dei motivi per cui dovresti usare una funzione wrapper per le tue query, piuttosto che eseguire direttamente le query sul DB.
@SebastianLenartowicz Un cattivo sviluppatore che sporca il codice con `mysql_real_escape_string` avrà il DB completamente aperto se si dimentica di chiamarlo una volta.È assolutamente possibile e nemmeno complicato scrivere un livello di astrazione che abbia un'interfaccia simile a PDO, usando segnaposto con nome per i valori, e un singolo `mysql_real_escape_string` chiamato quando necessario.
Va notato che le stored procedure di per sé non sono una protezione da SQLi, perché: 1. sebbene sia meno naturale in esse, possono comunque creare query mediante concatenazione di stringhe all'interno e quindi eseguirle e quindi sono aperte allo stesso tipodi problemi e 2. devi ancora emettere l'istruzione sql per chiamarli e quella query stessa può essere vulnerabile all'iniezione se non usi l'associazione di parametri.
@GodsBoss A meno che quello che stai facendo non sia veramente banale, provare a scrivere il tuo livello di astrazione DB è in genere un esercizio nei casi limite mancati e "oh, non lo fa già; hackeriamolo".Le librerie standard / ORM di terze parti esistono per un motivo, quindi non devi scriverne di tue e preoccuparti per sempre se hai perso un caso.
Sono d'accordo, ecco perché ci sono così tanti ORM famosi (come Hibernate o Doctrine per isntance) in varie lingue: usano query parametrizzate, sono spesso ben mantenute da persone che sanno cosa stanno facendo.Nella maggior parte dei casi, utilizzare bene queste funzioni ORM copre il 99,99% del lavoro attorno a SQLi. Ovviamente c'è sempre il rischio, che tutto non sia completamente igienizzato, di essere ingannato da un giovane hacker sovietico che ha scoperto che l'uso di un set di caratteri specifico può essere interpretatoin modo diverso e generare un'alterazione dell'input (esempio totalmente casuale), o avere una vecchia versione del database che è vulnerabile
Non conosco PHP ma so che in Java un'istruzione preparata può consentire a una query ripetuta di dover essere compilata solo una volta, il che può migliorare sostanzialmente i tempi di esecuzione: in molti casi è una microottimizzazione ma in altri è la differenza tra una sempliceserver e un server bloccato.
#2
+25
halfer
2020-04-21 15:53:52 UTC
view on stackexchange narkive permalink

Penso che la domanda principale qui sia perché l'escape di stringhe non è buono come gli altri metodi.

La risposta è che alcuni casi limite consentono alle iniezioni di scivolare anche se sono sfuggite. Stack Overflow ha diversi esempi qui.

#3
+14
Jefrey Sobreira Santos
2020-04-21 19:17:43 UTC
view on stackexchange narkive permalink

Anche se puoi stare al sicuro proteggendoti da SQLi che sfugge all'input dell'utente, è importante notare che potrebbe non essere sempre sufficiente. In questo terribile esempio, le virgolette non sono mai necessarie per eseguire una SQL injection di successo, nonostante la fuga:

  <? Php / * Questo è un esempio di cattiva pratica per diversi motivi. Questo codice non deve mai essere utilizzato in produzione. * / $ Post_id = mysql_real_escape_string ($ _ GET ['id']); $ qry = mysql_query ("SELECT title, text FROM posts WHERE id = $ post_id"); $ row = mysql_fetch_array ( $ qry); echo '<h1>'. $ row ['title']. '< / h1>'; echo $ row ['text'];  

Ora cosa succederebbe se si visitasse .php? id = -1 + UNION + ALL + SELECT + 1, version () ? Vediamo come va la query:

  SELECT title, text FROM posts WHERE id = -1 UNION ALL SELECT 1, version ()  

Certo che ci sono altri modi per risolverlo (ad es. utilizzando virgolette ed escaping o int-casting), ma usare istruzioni preparate è un modo per rimanere meno inclini a perdere queste cose e lasciare che il conducente si preoccupi di come includere l'input dell'utente nella query (anche perché , sebbene questo esempio sembri così facile da correggere, ci sono iniezioni SQL multilivello che consistono, fondamentalmente, nel salvataggio di parti di query SQL nel database sapendo che i dati del database verranno utilizzati in futuro come parte di un'altra query) .

Meglio prevenire che curare.

#4
+10
Machavity
2020-04-21 19:16:55 UTC
view on stackexchange narkive permalink

Perché stai facendo la stessa quantità di lavoro per una maggiore sicurezza

Un tropo comune menzionato contro PHP è mysqli_real_escape_string () (guarda quanto è lungo! Può ' t sono coerenti con la nomenclatura?), ma la maggior parte delle persone non si rende conto che l'API PHP chiama semplicemente l'API MySQL. E cosa sta facendo?

Questa funzione crea una stringa SQL legale da usare in un'istruzione SQL

In altre parole, quando usi questo , stai chiedendo a MySQL di disinfettare il valore in modo che sia "sicuro" da usare in SQL. Stai già chiedendo al database di lavorare per te in questo senso. L'intero processo ha questo aspetto

  1. Scappa dai dati non attendibili
  2. Assembla la query SQL finale (cioè metti i dati di escape nell'SQL)
  3. Analizza la query
  4. Esegui la query

Quando usi un'istruzione preparata, stai dicendo al tuo database che ha bisogno di farlo in un ordine diverso

  1. Analizza la query con i segnaposto
  2. Invia i dati per riempire i segnaposto, specificando il tipo di dati mentre procediamo
  3. Esegui la query
  4. Poiché inviamo i dati separatamente, stiamo svolgendo la stessa quantità di lavoro dell'escape, ma otteniamo il vantaggio di non avere dati non attendibili nel nostro SQL . In quanto tale, il motore non può mai confondere i dati forniti con le istruzioni SQL.

    C'è anche un vantaggio nascosto qui. Quello che potresti non capire è che una volta completato il passaggio n. 1, puoi eseguire i passaggi 2 e 3 più e più volte, a condizione che tutti debbano eseguire la stessa query, solo con dati diversi.

      $ prep = $ mysqli->prepare ('INSERT INTO lives_log (visitor_name, visitor_id) VALUES (?,?)'); $ prep->bind_param ('si', $ visitor_name, $ visitor_id); // questa funzione passa per referenceforeach ($ _ POST ['visitor_list'] as $ visitor_id = > $ visitor_name) $ prep->execute ();  

    Questa query trae vantaggio dal dover solo eseguire il loop sui dati e inviarli più e più volte, invece di aggiungere il sovraccarico dell'analisi ogni volta.

Considero questo un fallimento della progettazione del protocollo cablato, non mantenendo il codice ei dati separati fino in fondo.OTOH, utilizzando i parametri di bind, la stessa API della libreria client potrebbe avere il suo back-end modificato silenziosamente per utilizzare un nuovo e migliore protocollo di cablaggio futuro che * mantiene * le cose fuori banda piuttosto che cercare di eseguire l'escape.
Bella risposta.Tuttavia, molti driver di database implementano istruzioni preparate eseguendo l'escape lato client.Non sto dicendo che questa sia una buona cosa, ma puoi vedere che è comune nella pratica se guardi il codice sorgente per vari connettori DBAPI Python.
C'è anche il vantaggio del caching del piano in DB come Oracle per istruzioni eseguite con valori diversi ma stessa struttura (attenzione al bind peeking).
@paj28 PDO (che copre tutti i database) esegue la preparazione simulata, ma mysqli no
#5
+8
Anonymous
2020-04-21 20:01:55 UTC
view on stackexchange narkive permalink

Un buon motivo per non utilizzare mysql_real_escape_string : è deprecato”

mysql_real_escape_string

(PHP 4> = 4.3.0, PHP 5)

mysql_real_escape_string - Esegue l'escape di caratteri speciali in una stringa per l'uso in un'istruzione SQL

Avviso

Questa estensione è stata deprecata in PHP 5.5.0 ed è stato rimosso in PHP 7.0.0. Invece, dovrebbe essere usata l'estensione MySQLi o PDO_MySQL. Vedi anche MySQL: scelta di una guida API e relative FAQ per maggiori informazioni. Le alternative a questa funzione includono:

  mysqli_real_escape_string () PDO :: quote ()  

Fonte: mysql_real_escape_string

Il documento spiega anche che l'escaping dipende dal set di caratteri :

Il set di caratteri deve essere impostato a livello di server, o con la funzione API mysql_set_charset () affinché influenzi mysql_real_escape_string (). Vedere la sezione dei concetti sui set di caratteri per ulteriori informazioni.

Dovrei anche aggiungere che le procedure memorizzate non sono sempre "sicure", ad esempio quando contengono SQL dinamico ... non proteggono contro cattive pratiche di codifica. Ma in effetti dovresti usare le istruzioni parametrizzate , se vuoi utilizzare procedure memorizzate dipende da te.

"Perché è deprecato" è una specie di ragionamento circolare, poiché l'OP chiede già perché è stato deprecato ...
Questo non risponde al motivo per cui si preferiscono dichiarazioni preparate.L'intera libreria PHP mysql è stata deprecata a favore di mysqli o PDO, non solo `mysql_real_escape_string`.mysqli e PDO hanno funzioni esattamente equivalenti.Stanno tutti chiamando [la stessa funzione C sottostante] (https://dev.mysql.com/doc/refman/8.0/en/mysql-real-escape-string.html).
#6
+6
paj28
2020-04-21 20:25:09 UTC
view on stackexchange narkive permalink

Già alcune buone risposte e fornirò alcuni ulteriori chiarimenti:

Escaping

mysql_real_escape_string può essere usato in modo sicuro. Il consiglio con l'escaping è di utilizzare la funzione di escaping adatta al tuo database . È necessaria una funzione leggermente diversa per ogni database. La maggior parte dei sottili problemi di sicurezza provengono da persone che utilizzano il proprio disinfettante (ad es. Solo ' -> ' ') e non realizzano casi estremi. È comunque necessario utilizzare mysql_real_escape_string correttamente, inserendo il valore tra virgolette, ma questo (il principio, non le virgolette) è vero per la maggior parte delle difese, comprese le istruzioni preparate.

Istruzioni preparate

Le istruzioni preparate sono un ottimo modo per fermare l'iniezione SQL. Tuttavia, puoi ancora sbagliare, ho visto occasionalmente persone costruire dinamicamente un'istruzione SQL e costruire un'istruzione preparata da quella. Erano molto turbati quando abbiamo detto loro che era ancora insicuro, poiché avevamo detto loro di usare dichiarazioni preparate! Inoltre, il codice con cui si finisce con l'utilizzo di istruzioni preparate è un po 'sgradevole. Non in modo importante, ma solo leggermente esteticamente stridente.

Alcuni connettori di database implementano istruzioni preparate usando l'escaping internamente (penso che psychopg per Python / Postgres lo faccia). Con altri database (Oracle è uno) il protocollo ha un supporto specifico per i parametri, quindi sono tenuti completamente separati dalla query.

Stored procedure

Le stored procedure non interrompono necessariamente l'iniezione SQL. Alcuni connettori ti consentono di richiamarli direttamente come un'istruzione preparata. Ma vengono spesso chiamati da SQL, dove è comunque necessario passare in sicurezza i dati in SQL. È anche possibile che una stored procedure disponga di SQL injection internamente, quindi è pericoloso anche se chiamato con un'istruzione preparata. Penso che questo consiglio derivi principalmente dalla confusione. Gli addetti alla sicurezza in genere non sono DBA e sono vaghi sulla differenza tra istruzioni preparate, query parametrizzate (un altro nome per istruzioni preparate) e procedure memorizzate (qualcosa di diverso). E questo consiglio è persistito in quanto vi sono alcuni vantaggi in termini di sicurezza per le stored procedure. Consentono di applicare la logica aziendale a livello di database, per consentire un accesso diretto sicuro al database o come meccanismo di difesa in profondità.

Sintassi di query sicura del tipo

Il modo in cui consiglio di interrompere l'iniezione SQL consiste nell'usare un meccanismo di query indipendente dai tipi. Ce ne sono molti, inclusa la maggior parte degli ORM (Hibernate, SQLAlchemy, ecc.) Così come alcune librerie / funzionalità non ORM come LINQ o jOOQ. Questi proteggono dall'iniezione SQL, forniscono un buon codice estetico ed è anche più difficile usarli in modo sbagliato e finire con l'iniezione SQL. Personalmente, sono un grande fan degli ORM, ma non tutti lo sono. Per sicurezza, il punto chiave non è che utilizzi un ORM, ma che utilizzi un sistema di query indipendente dai tipi.

Ok, spero che questo chiarisca le cose per te. Bella domanda.

Un altro modo in cui le dichiarazioni preparate possono andare storte è che ci sono casi in cui è necessario ma non applicabile.Ad esempio, un'istruzione preparata non ti consentirà di parametrizzare il nome di una tabella o di una colonna.Se devi modificare il nome della tabella / colonna in base all'input dell'utente, le istruzioni preparate non ti aiuteranno.Devi ripiegare sulla corretta sanificazione dell'input dell'utente (preferibilmente con una whitelist di valori consentiti) e inserire i dati direttamente nella query.È un caso limite facile da perdere quando si lavora con affermazioni preparate.
@ConorMancone - Buon punto.Potresti trovare interessante questo [problema di SQLAlchemy] (https://github.com/sqlalchemy/sqlalchemy/issues/4481).
Cosa intendi con "il codice con cui finisci di usare istruzioni preparate è un po 'sgradevole"?
@Schwern - Solo che non sembra carino, specialmente con query complesse.Invece di introdurre i dati dove vengono utilizzati, hai un?come segnaposto e una riga successiva che allega i dati.Meno male con i parametri denominati.
#7
+3
Erik A
2020-04-21 23:02:04 UTC
view on stackexchange narkive permalink

Un ulteriore argomento, non InfoSec, è che i parametri potenzialmente consentono query più veloci e un minore utilizzo della memoria.

Utilizzando i parametri, i dati e la query sono separati, il che è particolarmente importante quando si inseriscono stringhe molto grandi e campi binari (l'intera stringa deve essere elaborata dalla funzione escape (che la estende e potrebbe richiedere la copia dell'intera stringa), e quindi analizzata di nuovo dal motore SQL, mentre un parametro deve solo essere passato e non analizzato) .

Alcuni connettori di database consentono anche il raggruppamento di parametri, che evita di dover avere l'intera stringa in memoria in una volta. La suddivisione in blocchi utilizzando la concatenazione di stringhe non è mai un'opzione, poiché i dati fanno parte della stringa SQL e quindi la stringa SQL non può essere analizzata senza di essa.

Poiché non c'è alcun vantaggio nell'usare la concatenazione di stringhe con una funzione di escape rispetto all'uso dei parametri, e ce ne sono molti per l'utilizzo dei parametri sulla concatenazione di stringhe, è logico che stiamo spingendo verso i parametri. Ciò ha portato a funzioni di escape deprecate, il che introduce potenziali problemi di sicurezza in futuro, il che rafforza la necessità di non utilizzarle.

#8
+1
jmoreno
2020-04-22 08:20:30 UTC
view on stackexchange narkive permalink

Sia le stored procedure che le istruzioni preparate limitano l'ambito potenziale utilizzando i parametri. call GetUserWithName ('jrmoreno'); offre meno opportunità di modificare la query, non nessuna opportunità. Si noti che le stored procedure parametrizzate tramite istruzioni preparate offrono ancora meno call GetUserWithName (@userName); rispetto alle normali stored procedure.

Inoltre, l'utilizzo di stored procedure apre a un diverso tipo di sql injection: sql dinamico all'interno della stored procedure.

Per quanto riguarda il motivo per cui utilizzare le istruzioni preparate, le istruzioni preparate sono un protocollo binario in cui i parametri hanno tipi e dimensioni fisse. Quando viene elaborato dal server è impossibile che un numero sia qualcosa di diverso da un numero o che una stringa si estenda oltre i suoi confini e venga trattata come più comandi sql (a condizione che quella stringa non sia utilizzata per creare sql dinamico all'interno il motore sql).

L'escape di una stringa non può darti lo stesso livello di sicurezza.

Va notato che `call Get User With Name ('$ name');` con `$ name` ottenuto dall'input dell'utente è ancora rischioso.E se "$ name =" jmoreno '); rilascia il database; - "`?
#9
+1
Ian Ringrose
2020-04-22 17:43:29 UTC
view on stackexchange narkive permalink

Posso avere una politica per utilizzare sempre procedure memorizzate e / o istruzioni preparate con qualsiasi database per cui scrivo software in un dato giorno. Il mio codice c # (ad esempio) ha quindi lo stesso aspetto indipendentemente dal database scelto dal mio attuale datore di lavoro, quindi è facile individuare quando non sto usando dichiarazioni preparate ecc.

Le dichiarazioni preparate non sono importanti, cos'è le importazioni mai utilizzando operatori di stringa per creare l'SQL da inviare al database.

mysql_real_escape_string () è un caso spaziale che è solo l'opzione per un database, quindi come imparare qualcosa che potrebbe non essere utile per il database successivo contro cui devo codificare?

#10
+1
Damon
2020-04-23 00:13:46 UTC
view on stackexchange narkive permalink

Le stored procedure sono superiori non solo perché sono una difesa efficace contro alcuni attacchi, inclusa l'iniezione. Sono superiori perché ottieni di più facendo di meno e in modo più sicuro, con una "prova" di sicurezza de facto. Mentre il semplice fatto di eseguire l'escape di stringhe è ben lungi dal fornire quella "prova".

In che modo?

Una stringa di query, anche se i dati sono correttamente sottoposti a escape, è un pezzo di testo. Il testo è antipatico per natura. Il testo viene analizzato, il che richiede tempo e può andare storto in molti modi, quindi il motore di database fa qualcosa . Che cosa fa? Non puoi mai essere sicuro al 100%.

Potresti dimenticare di chiamare la funzione di escape della stringa, o la funzione di escape della stringa potrebbe essere difettosa in un modo che può essere sfruttato. Improbabile, ma anche su una query con escape corretto al 100%, è in linea di principio possibile fare qualcosa di diverso. Oh certo, c'è ancora il controllo degli accessi e cose del genere per limitare i possibili danni, ma qualunque cosa. Resta il fatto che in linea di principio stai lanciando una stringa al motore del database che non è molto diversa dall'invio di codice eseguibile, e quindi ti aspetti che faccia qualcosa , che si spera sia esattamente quello che vuoi .

Le stored procedure, d'altra parte, incapsulano esattamente una operazione specificata, mai nulla di diverso. Invia quello che vuoi, l'operazione effettiva che avverrà è già definita.
Le stored procedure vengono, in linea di principio, analizzate e ottimizzate esattamente una volta e (possibilmente, non necessariamente, ma almeno in teoria) compilate in una rappresentazione particolarmente veloce (ad esempio una qualche forma di bytecode).

Quindi ... ti sei dimenticato di eseguire l'escape di una stringa? Che importa. La funzione di escape della stringa non funziona correttamente? Che importa. La procedura memorizzata non può mai fare nulla che non le avevi detto di fare, in un momento precedente. La cosa peggiore che accada è che qualcuno che cerca di sfruttare il server riesce a inserire dei rifiuti come nome utente o simili. Chi se ne frega.

Quindi, ottieni una sicurezza molto migliore e anche il server deve fare meno lavoro (ad es. le query vengono eseguite più velocemente). Si vince su entrambi i lati (cosa rara dato che di solito si ha un compromesso).

Inoltre, da un punto di vista puramente "estetico", non che sia importante in pratica, le cose sono il modo in cui dovrebbero essere . Il database riceve solo dati ed esegue un qualche tipo di programma per quel conto, a sua discrezione.

#11
  0
Konchog
2020-04-22 14:51:13 UTC
view on stackexchange narkive permalink

A livello strategico, il problema ha a che fare con la vigilanza. Quando scriviamo codice, se dobbiamo fare qualcosa in più per garantire la prevenzione di un problema di sicurezza (o sicurezza, o qualsiasi altra forma di qualità / prestazioni), allora dobbiamo essere vigili nel farlo effettivamente.

Questo è, credo, il problema principale con l'utilizzo di una funzione di "fuga".

Ciò che aggrava il problema è che, perché la funzione 'escape' viene eseguita al di fuori della costruzione / valutazione della query stessa, non esiste un modo semplice o efficiente per poter controllare tutte le query riguardanti la presenza o l'assenza di escape.

Per evitare questa debolezza è necessario trasformare la composizione escape / sql in una funzione, che è essenzialmente ciò che è un'istruzione preparata, o utilizzare un livello astratto per il proprio sql (ad esempio una sorta di ORM).

Essendo una scimmia SQL, nessuna delle due opzioni è meravigliosa. Soprattutto quando si ha a che fare con strutture SQL complesse (ad es. Tabelle di chiavi primarie a 3 campi con diversi join a sinistra, incluso l'utilizzo della stessa tabella due volte, con alias: non insolito per le strutture ad albero).

Non sto parlando teoricamente: questa è esperienza pratica. Abbiamo iniziato a usare meccanismi di fuga e poi siamo stati scoperti, fortunatamente da una penna. agenzia di test - che ha trovato una via di fuga mancante (il caso in mano era il valore di un cookie di sessione che non era stato evitato). Lo hanno dimostrato iniettando "select sleep (10);" - un modo brillante di testare / dimostrare le iniezioni.

(Andando leggermente fuori tema è quasi impossibile per il team di sviluppo scrivere test di iniezione per il proprio codice. Tendiamo a vedere le cose solo da una posizione. Questo è il motivo per cui l'azienda consiglia sempre agenzie di pen. test di terze parti, completamente indipendenti.)

Quindi, sì. escape () come standalone è un modo molto debole per garantire la protezione dall'iniezione. Si desidera sempre integrare la protezione come parte della costruzione della query, perché è importante non dipendere dalla vigilanza, ma piuttosto essere costretti, per impostazione predefinita, a garantire che gli attacchi sql injection siano tenuti in considerazione.

#12
  0
Dharman
2020-04-22 21:02:33 UTC
view on stackexchange narkive permalink

Devi capire che mysql_real_escape_string () non è un mezzo per la protezione contro l'iniezione SQL. È semplicemente un hack che ha lo scopo di ridurre il danno e limitare i potenziali vettori di attacco. Niente nel nome o nella documentazione ufficiale di mysql_real_escape_string () dice che questa funzione deve essere utilizzata per prevenire l'iniezione SQL.

SQL injection si verifica quando si consente ai dati variabili di far parte della stringa SQL. Quando si crea SQL con dati dinamici è difficile garantire che l'SQL non venga interrotto. Un input non autorizzato potrebbe rompere l'SQL e causare danni ai dati o far perdere le informazioni.

SQL dovrebbe essere costante, proprio come il resto del codice. Consentire l'input di variabili in SQL è vulnerabile ad attacchi simili a eval () con input di variabili. Non puoi mai essere sicuro di cosa viene eseguito.

Per evitare ciò è necessario assicurarsi che l'SQL sia costante e non cambi con l'input. La soluzione a questo sono i segnaposto. Hai parametrizzato i dati e utilizzato i segnaposto nei punti in cui andranno i letterali. Non è necessaria alcuna fuga. Quindi si prepara tale dichiarazione e si passano i dati separatamente durante l'esecuzione. L'SQL è sempre lo stesso ei dati non hanno modo di influenzare l'SQL e cambiarne il comportamento.

Le stored procedure non sono un modo sicuro per prevenire le SQL injection. Simile all'evasione, limita solo i vettori di attacco.



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...