2010-03-04 6 views
8

Eventuali duplicati:
Can I protect against SQL Injection by escaping single-quote and surrounding user input with single-quotes?In che modo questo codice di query SQL può essere interrotto/sfruttato dall'input dell'utente?

Abbiamo un'applicazione legacy che non fa query che utilizzano parametri posizionali, e c'è SQL ovunque. È stato deciso (prima che iniziassi qui) che, poiché l'input dell'utente può contenere apostrofi, ogni stringa di input deve essere sfuggita manualmente per quegli apostrofi.

Ecco il codice essenziale originale (non scritto da me), tradotto in C# per il consumo facile:

private string _Escape(string input) 
{ 
    return input.Replace("'", "''"); 
} 

private bool _IsValidLogin(string userName, string password) 
{ 
    string sql = 
     string.Format 
     (
      @"SELECT COUNT(*) FROM UserAccounts 
       WHERE UserName = '{0}' AND Password = '{1}'", 
      _Escape(userName), 
      _Escape(password) 
     ); 
    // ... 
}

Questo sembra davvero come può essere rotto in qualche modo, ma io sono in perdita su come potrebbe essere sfruttato dall'input dell'utente. Si supponga che l'input dell'utente non sia filtrato finché non tocca _IsValidLogin e si dimentichi che le password sembrano essere archiviate in testo normale.

La soluzione a riva in su per bene è ovvio - usano parametri posizionali - ma ho bisogno di alcune munizioni a dimostrare alla direzione perché/come questo codice è insicuro così il tempo/$ può essere assegnato per esso per ottenere fisso.

Nota: Io sono supponendo che questo può essere rotto, ma che in realtà non può essere il caso. Non sono una superstar della SQL.

Nota 2: Ho espresso questa domanda come indipendente dal database, ma se riesci a sfruttare questo codice per un determinato motore, accolgo con favore il tuo contributo.

+1

Vale la pena leggere qui se non l'hai già fatto: http://stackoverflow.com/questions/139199/can-i-protect-against-sql-injection-by-escaping-single-quote-and- circostante-user –

+0

@Nick: Grazie, non l'ho visto. Chiuderò questa domanda come un duplicato. –

+0

Chiuso su richiesta dell'autore. –

risposta

3

Potrebbe essere escluso dai backslash.

password = foo\' OR 1=1 -- 

diventa:

password = foo\'' OR 1=1 -- 

la query:

"SELECT COUNT(*) FROM UserAccounts 
       WHERE UserName = '{0}' AND Password = 'foo\'' OR 1=1 --'" 

-- è il marchio commento in questo esempio.

La soluzione presuppone che nel programma vengano applicati solo filtri (duplicati) apostrofi.

+0

Non posso dire per altri database, ma il backslash non sembra essere un carattere di escape in MSSQL e sarebbe semplicemente usato letteralmente. Il tuo esempio cercherebbe semplicemente le password di ''foo \' OR 1 = 1 --' –

0

Bene, non riesco a vedere un modo in cui è vulnerabile. Quindi, discutiamo un motivo diverso per cui dovrebbe essere cambiato --- è piuttosto inefficace. In MSSQL (e, credo, nella maggior parte degli altri server SQL di fascia alta), le query vengono analizzate e il piano di esecuzione viene escogitato, quindi vengono archiviati query e piano. Se viene richiesta nuovamente una copia exact della query, viene utilizzato il piano di esecuzione salvato. I parametri non influenzano questo, quindi se si usano i parametri, riutilizzerà i piani; se incorpori il testo, non lo farà mai.

+0

È vulnerabile. L'esempio non utilizza alcun legame ai parametri. – erenon