Domanda:
Come sconfiggere il raddoppio degli apostrofi per creare un attacco SQLi?
DomBat
2015-12-18 15:35:42 UTC
view on stackexchange narkive permalink

So che alcuni sviluppatori raddoppiano gli apostrofi per mitigare SQLi. (Questo è quando l'input è "così diventa" ")

C'è un modo per battere questo?

Questo è su MS SQl Server.

Utilizzare [istruzioni preparate] (https://technet.microsoft.com/en-us/library/ms175528 (v = sql.105) .aspx) è una buona tecnica, l'idea è di lasciare che il database gestisca tutte le sfumature escaping e formattazione in modo da non doverlo fare. Puoi trovare un esempio di come farlo in PHP [qui] (http://php.net/manual/en/function.sqlsrv-prepare.php)
Vedi anche https://stackoverflow.com/q/15537368/781723
Tre risposte:
#1
+39
Mark Buffalo
2015-12-18 19:35:30 UTC
view on stackexchange narkive permalink

Cerco di mostrare entrambi i lati dello spettro di sicurezza. La sicurezza è importante, quindi non dovresti solo sapere come sconfiggerla, ma anche come implementarla. Quindi, elencherò prima una prevenzione. Se non vuoi leggere questo, scorri verso il basso.

Come posso impedire l'iniezione di SQL?


Raddoppiare gli apostrofi è non la risposta quando si tratta di sicurezza e può portare all'insicurezza. La risposta dipende dal linguaggio di programmazione che stai utilizzando.

  • Per SQL Server / Oracle / MySQL
    • Con Java, usa CallableStatements e PreparedStatements correttamente.
    • Con PHP, avrai bisogno delle istruzioni preparate appropriate.
    • Con C # / VB.NET, avrai bisogno di query parametrizzate.

Nota che questi sono tutti gli stessi concetti in ogni lingua. Hanno solo nomi diversi.

Anche con istruzioni preparate / richiamabili o query con parametri, quanto segue non è corretto:

  // Codice errato, non usa la stringa sqlString = "SELECT * FROM [table] WHERE [col] = '" + something + "' AND [col2] = @Param";  

Non devi mai concatena le tue variabili SQL.

Con il server SQL, a seconda della lingua prescelta, la query dovrebbe essere simile a questa:

  • C #

      using (SqlCommand command = new ("SELECT * FROM [tab] WHERE LName = @LName", connection)) {// Aggiungi nuovo SqlParameter al comando. command.Parameters.Add (new SqlParameter ("LName", txtBox.Test)); // Leggi i risultati SELECT. Lettore SqlDataReader = command.ExecuteReader (); while (reader.Read ()) {}}  
  • Java

      Connection con = DriverManager.getConnection ("database- connection-string "," name "," pass "); // I punti interrogativi sono le variabili legate che vengono analizzate nell'ordine di colonna definito. PreparedStatement findLName = con.prepareStatement ("SELECT * FROM [tab] WHERE LName =?");
    // L'ordine in cui vengono visualizzati i punti interrogativi. Puoi averne più di uno in una dichiarazione preparata. Il primo è "1", il secondo è "2" e così via. FindLName.setString (1, Lastname); findLName.executeQuery (); Statement stmt = con.createStatement ();  
  • PHP

    Controlla w3schools per un esempio, non voglio che la mia risposta diventi troppo lunga.

Nota che questo ancora non elimina la potenziale iniezione di script su una pagina web. È possibile inserire esattamente come richiesto, entro intervalli accettabili, e quindi visualizzare i risultati in HTML.

Se inseriscono quanto segue (esempio semplificato):

  <script> window.location.href = "hxxp: //www.mymalwarewebsite.com/"; < / script>  

... e se invii il risultato alla tua pagina, allora sei nei guai. Che cosa succede se rimuovi qualcosa da <script> a < / script> ? E se inserissero:

  <scri<script>pt> window.location.href = 'hxxp: //www.mymalwarewebsite.com/'; < / scri<script>pt>  

...? Se rimuovi i tag script con sostituisci, sei ancora bloccato con quell'exploit.

Ciò che desideri veramente è il seguente in aggiunta a quanto sopra :

Stai zitto, Mark! Come faccio a battere il raddoppio degli apostrofi?


  • Potresti essere in grado di batterli in modi diversi; potresti essere in grado di forzare vari database SQL a tradurre unicode nel set di caratteri locale . Ad esempio, Ā potrebbe essere convertito in A . Ancora peggio: U + 02BC o ʼ verrebbe tradotto come ', che è U + 0027 . Questo si chiama contrabbando basato su Unicode .
    • Il raddoppio delle virgolette non funziona nelle versioni precedenti di MySQL.
  • Sebbene non sia realmente un attacco SQL injection, puoi provare a forzare il sito web a iniettare codice dannoso da mostrare ai propri utenti. Puoi provare a inserire tag di script (leggi sopra per un esempio). Immagina di iniettare un download drive-by quando le persone visualizzano la tua pagina o un elenco di utenti.
  • Sebbene non sia tecnicamente un attacco SQL injection, potresti essere in grado di battere questa protezione guardando attraverso la console nel tuo browser e controllando gli interi inviati al database, quindi modificare la richiesta. Questo è chiamato exploit Riferimento diretto agli oggetti. Esistono vari strumenti che possono farlo. Le dichiarazioni preparate non ti proteggeranno da questo attacco. Leggi l'articolo OWASP
Solo un commento su Java: `StringEscapeUtils` è ** antico ** e piuttosto spazzatura. Se vuoi davvero uscire dall'HTML correttamente, devi usare un disinfettante HTML appropriato come [quello di OWASP] (https://github.com/owasp/java-html-sanitizer).
Voglio solo aggiungere che "istruzioni preparate" e "query parametrizzate" sono due nomi per lo stesso concetto. Diversi linguaggi di programmazione si riferiscono a loro in modo diverso.
Non sono sicuro del motivo per cui parli di XSS o Direct Object Reference. Voglio dire, certo che sono problemi che non vengono evitati raddoppiando le virgolette singole, ma nemmeno CSRF, fissazione della sessione e così via. Ma nessuno di loro ha niente a che fare con SQL Injection, che è l'argomento della domanda.
@tim Il mio ragionamento è che lo scopo di un attacco SQL injection è quello di influenzare negativamente gli utenti / il sito web / l'app. Dato il comando a `UpdateUser (int)`, se questo non viene gestito correttamente sul lato server, è possibile modificare la richiesta per aggiornare * qualsiasi * id. Ciò significa che puoi installarti come amministratore se conosci l'ID utente dell'amministratore. Da lì, puoi probabilmente accedere a cose a cui la maggior parte degli utenti non è autorizzata e causare molti problemi. Allo stesso modo, essere in grado di iniettare un drive-by-download su tutti i visitatori del tuo sito web potrebbe consentirti di rubare molte più informazioni di quelle memorizzate nel database.
@DerekW D'accordo, stesso concetto. Voglio che le persone sappiano che spesso vengono chiamate cose diverse in altre lingue.
#2
+14
tim
2015-12-18 20:18:03 UTC
view on stackexchange narkive permalink

C'è un modo per battere questo?

Forse (almeno con MySQL). Ed è davvero semplice (non servono codifiche speciali o l'assenza di virgolette o altro):

  \ '[injection] - -  

Quindi, ad esempio, hai questa query:

  SELECT FROM table WHERE user = '[INPUT]';  

L'input è \ "[injection] - - , ma con " raddoppiato, diventa: \ '' [injection] - - , che ci porta a questa query :

  SELECT FROM table WHERE user = '\' '[injection] - -';  

La parte iniettata verrà eseguita come query, poiché non è più tra virgolette.

L'unica difesa adeguata contro l'iniezione SQL sono le istruzioni preparate. Inoltre non sono difficili da usare e spesso danno come risultato un codice migliore. Non ci sono davvero buone scuse per difese fatte in casa come il raddoppio delle virgolette.

// update: Sembra che questo non sarebbe effettivamente possibile con MSSQL. Quindi ciò lascerebbe i due problemi già menzionati nelle altre risposte: è ancora vulnerabile se non vengono utilizzate virgolette nella query, o (possibilmente) per determinati set di caratteri.

Dipende anche da come avviene effettivamente il raddoppio. Se, ad esempio, viene eseguito tramite il database, potrebbe essere vulnerabile.

Funziona su MSSQL? So che funziona su MySQL, ma la domanda riguarda MSSQL.
@paj28 grazie, questo è un ottimo punto. Ho solo pensato che avrebbe funzionato (non ho accesso a MSSQL per testare in questo momento), ma penso che tu abbia ragione, probabilmente non lo farebbe. Ecco una [domanda molto simile su stackoverflow] (https://stackoverflow.com/questions/15537368/).
#3
+7
Volker
2015-12-18 18:52:44 UTC
view on stackexchange narkive permalink

Ciò impedisce solo attacchi di SQL injection tramite parametri stringa. A volte, il parametro è un numero intero (si pensi a http://www.example.org/?page=3 ), quindi non è necessario un apostrofo. A volte puoi verificare se i parametri sono vulnerabili se sostituisci page = 3 con page = 1 + 2 , ad esempio.



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