it-swarm.it

Le procedure memorizzate impediscono l'iniezione di SQL?

È vero che le procedure memorizzate impediscono gli attacchi SQL injection contro i database PostgreSQL? Ho fatto una piccola ricerca e ho scoperto che SQL Server, Oracle e MySQL non sono sicuri contro l'iniezione di SQL anche se utilizziamo solo procedure memorizzate. Tuttavia, questo problema non esiste in PostgreSQL.

L'implementazione della procedura memorizzata nel core PostgreSQL impedisce gli attacchi SQL injection o è qualcos'altro? O PostgreSQL è anche suscettibile all'iniezione SQL anche se utilizziamo solo stored procedure? In tal caso, mostrami un esempio (ad esempio libro, sito, carta, ecc.).

84
Am1rr3zA

No, le stored procedure non impediscono l'iniezione di SQL. Ecco un esempio reale (da un'app interna creata da qualcuno dove lavoro) di una procedura memorizzata che purtroppo consente l'iniezione SQL:

Questo codice server SQL:

CREATE PROCEDURE [dbo].[sp_colunmName2]   
    @columnName as nvarchar(30),
    @type as nvarchar(30), 
    @searchText as nvarchar(30)           
AS
BEGIN
    DECLARE @SQLStatement NVARCHAR(4000)
    BEGIN
        SELECT @SQLStatement = 'select * from Stations where ' 
            + @columnName + ' ' + @type + ' ' + '''' + @searchText + '''' 
        EXEC(@SQLStatement)
    END      
END
GO

approssimativamente equivalente a postgres:

CREATE or replace FUNCTION public.sp_colunmName2 (
    columnName  varchar(30),
    type varchar(30), 
    searchText  varchar(30) ) RETURNS SETOF stations LANGUAGE plpgsql            
AS
$$
DECLARE SQLStatement VARCHAR(4000);
BEGIN
    SQLStatement = 'select * from Stations where ' 
            || columnName || ' ' || type || ' ' || ''''|| searchText || '''';
    RETURN QUERY EXECUTE  SQLStatement;
END
$$;

L'idea dello sviluppatore era quella di creare una procedura di ricerca versatile, ma il risultato è che la clausola WHERE può contenere tutto ciò che l'utente desidera, consentendo una visita da tavolini Bobby .

Non importa se usi istruzioni SQL o stored procedure. Ciò che conta è se il tuo SQL utilizza parametri o stringhe concatenate. I parametri impediscono l'iniezione SQL; stringhe concatenate consentono l'iniezione SQL.

71
Kyralessa

Gli attacchi SQL Injection sono quelli in cui l'input non attendibile viene aggiunto direttamente alle query, consentendo all'utente di eseguire in modo efficace codice arbitrario, come illustrato in questo fumetto canonico XKCD.

Quindi, otteniamo la situazione:

 userInput = getFromHTML # "Robert ') Elimina gli studenti della tabella; -" 
 
 Query = "Seleziona * dagli studenti in cui studentName =" + userInput 

Le Stored procedure sono, in generale, buone difese contro gli attacchi di SQL injection perché i parametri in arrivo non vengono mai analizzati.

In una procedura memorizzata, nella maggior parte dei DB (e dei programmi, non dimenticare che le query precompilate contano come procedure memorizzate) sono simili alle seguenti:

 
 
 crea il procdure foo memorizzato (
 seleziona * dagli studenti in cui studentName =: 1 
); 
 

Quindi, quando il programma desidera accedere, chiama foo(userInput) e recupera felicemente il risultato.

Una procedura memorizzata non è una difesa magica contro SQL-Injection, poiché le persone sono abbastanza in grado di scrivere procedure memorizzate non valide . Tuttavia, le query precompilate, archiviate nel database o nel programma, sono molto più difficili da aprire falle di sicurezza in se capisci come funziona SQL-Injection.

Puoi leggere di più su SQL-Injection:

46

Sì, in una certa misura.
Le sole Stored Procedure non impediranno l'iniezione di SQL.

Vorrei prima citare SQL Injection da OWASP

Un attacco di iniezione SQL consiste nell'inserimento o "iniezione" di una query SQL tramite i dati di input dal client all'applicazione. Un exploit SQL injection riuscito può leggere i dati sensibili dal database, modificare i dati del database (Inserisci/Aggiorna/Elimina), eseguire operazioni di amministrazione sul database (come arrestare il DBMS), recuperare il contenuto di un determinato file presente sul file DBMS sistema e in alcuni casi impartire comandi al sistema operativo. Gli attacchi di iniezione SQL sono un tipo di attacco di iniezione, in cui i comandi SQL vengono immessi nell'input del piano dati per effettuare l'esecuzione di comandi SQL predefiniti.

È necessario disinfettare gli input dell'utente e non concatenare le istruzioni SQL, anche se si utilizza la stored procedure.

Jeff Attwood ha spiegato le conseguenze della concatenazione di sql in " Dammi SQL parametrizzato o dammi la morte "

Di seguito è riportato il fumetto interessante che mi viene in mente ogni volta che sento SQL Injection alt text Penso che tu abbia capito il punto :-)

Dai un'occhiata a SQL Injection Prevention Cheat Sheet , i metodi di prevenzione sono ben spiegati ...

29
CoderHawk

La concatenazione di stringhe è la causa dell'iniezione SQL. Questo è evitato usando la parametrizzazione.

Le procedure memorizzate aggiungono un ulteriore livello di sicurezza applicando una sintassi non valida quando si concatena, ma non sono "più sicure" se si usa, diciamo, SQL dinamico in esse.

Pertanto, il codice sopra riportato è causato dalla concatenazione di queste stringhe

  • exec sp_GetUser '
  • x' AND 1=(SELECT COUNT(*) FROM Client); --
  • ' , '
  • monkey
  • '

Ciò fornisce una sintassi non valida, per fortuna

Parametrizzando darebbe

exec sp_GetUser 'x'' AND 1=(SELECT COUNT(*) FROM Client); --' , 'monkey'

Questo significa

  • @UserName = x' AND 1=(SELECT COUNT(*) FROM Client); --
  • @Password = monkey

Ora, nel codice sopra non otterrai righe perché suppongo che tu non abbia alcun utente x' AND 1=(SELECT COUNT(*) FROM Client); --

Se il proc memorizzato appare così (usando SQL dinamico concatenato ), la tua chiamata proc memorizzata parametrizzata consentirà comunque l'iniezione SQL

...
SET @sql = 'SELECT userName from users where userName = ''' + 
               @UserName + 
               ''' and userPass = ''' +
               @Password +
               ''''
EXEC (@sql)
....

Quindi, come dimostrato, la concatenazione di stringhe è il principale nemico dell'iniezione SQL

Le procedure memorizzate aggiungono incapsulamento, gestione delle transazioni, autorizzazioni ridotte, ecc., Ma possono comunque essere abusate per l'iniezione SQL.

Puoi vedere Stack Overflow per ulteriori informazioni su parametrizzazione

12
gbn

"Gli attacchi SQL injection si verificano quando input dell'utente è codificato in modo errato. In genere, l'input dell'utente è costituito da alcuni dati che l'utente invia con la sua query, ovvero i valori in $_GET, $_POST, $_COOKIE, $_REQUEST, o $_SERVER matrici. Tuttavia, l'input dell'utente può anche provenire da una varietà di altre fonti, come socket, siti Web remoti, file, ecc. Pertanto, dovresti davvero trattare tutto tranne le costanti (piace 'foobar') come input dell'utente . "

Di recente ho studiato a fondo questo argomento e vorrei condividere con altri materiale abbastanza interessante, rendendo così questo post più completo e istruttivo per tutti.



Da YouTube


Da Wikipedia


Da OWASP


Da PHP Manuale


Da Microsoft e Oracle


Overflow dello stack


Scanner per iniezione SQL

10
Ilia Rostovtsev

Le procedure memorizzate non impediscono magicamente l'iniezione di SQL, ma rendono molto più semplice prevenirlo. Tutto quello che devi fare è qualcosa di simile al seguente (esempio Postgres):

CREATE OR REPLACE FUNCTION my_func (
  IN in_user_id INT 
)
[snip]
  SELECT user_id, name, address FROM my_table WHERE user_id = in_user_id; --BAM! SQL INJECTION IMMUNE!!
[snip]

Questo è tutto! Il problema si presenta solo quando si forma una query tramite concatenazione di stringhe (ovvero SQL dinamico) e anche in quei casi potresti essere in grado di associare! (Dipende dal database.)

Come evitare l'iniezione SQL nella query dinamica:

Passaggio 1) Chiediti se hai davvero bisogno di una query dinamica. Se stai mettendo insieme le stringhe solo per impostare l'input, probabilmente stai sbagliando. (Esistono eccezioni a questa regola: un'eccezione è per la segnalazione di query su alcuni database, potresti avere problemi di prestazioni se non lo costringi a compilare una nuova query con ogni esecuzione. Ma cerca questo problema prima di saltare a quello. )

Passaggio 2) Ricercare il modo corretto di impostare la variabile per il proprio RDBMS. Ad esempio, Oracle ti consente di fare quanto segue (citando dai loro documenti):

sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE ' 
           || v_column || ' = :2';
EXECUTE IMMEDIATE sql_stmt USING amount, column_value; --INJECTION IMMUNE!!

Qui non stai ancora concatenando l'input. Stai vincolando in modo sicuro! Evviva!

Se il tuo database non supporta qualcosa di simile a quanto sopra (speriamo che nessuno di loro sia ancora così male, ma non sarei sorpreso) - o se devi ancora concatenare il tuo input (come nel caso "a volte" di segnalazione di query come Ho accennato sopra), quindi è necessario utilizzare una corretta funzione di escape. Non scriverlo da solo. Ad esempio postgres fornisce la funzione quote_literal (). Quindi avresti eseguito:

sql_stmt := 'SELECT salary FROM employees WHERE name = ' || quote_literal(in_name);

In questo modo se in_name è qualcosa di subdolo come '[snip] o 1 = 1' (la parte "o 1 = 1" significa selezionare tutte le righe, permettendo all'utente di vedere gli stipendi che non dovrebbe!), Allora quote_literal salva il tuo sedere di rendendo la stringa risultante:

SELECT salary FROM employees WHERE name = '[snip] or 1=1'

Nessun risultato verrà trovato (a meno che tu non abbia alcuni dipendenti con nomi davvero strani.)

Questa è la sostanza! Ora lascia che ti lasci un link a un post classico del guru Oracle Tom Kyte sull'argomento SQL Injection, per riportare il punto a casa: Linky

2
MWDB