Domanda

Ho del codice che utilizza query parametrizzate per impedire l'iniezione, ma devo anche essere in grado di costruire dinamicamente la query indipendentemente dalla struttura della tabella. Qual è il modo corretto per farlo?

Ecco un esempio, supponiamo di avere una tabella con colonne Nome, Indirizzo, Telefono. Ho una pagina web in cui eseguo Mostra colonne e popolo un menu a discesa con loro come opzioni.

Successivamente, ho una casella di testo chiamata Cerca . Questa casella di testo viene utilizzata come parametro.

Attualmente il mio codice è simile al seguente:

result = pquery('SELECT * FROM contacts WHERE `' + escape(column) + '`=?', search);

Ho comunque una sensazione icky da esso. Il motivo per cui sto usando query con parametri è di evitare di usare escape . Inoltre, escape probabilmente non è progettato per sfuggire ai nomi delle colonne.

Come posso assicurarmi che funzioni nel modo che intendo?

Modifica Il motivo per cui ho bisogno di query dinamiche è che lo schema è configurabile dall'utente e non sarò in giro per riparare nulla di hardcoded.

È stato utile?

Soluzione

Invece di passare i nomi delle colonne, basta passare un identificatore che il codice tradurrà in un nome di colonna usando una tabella codificata. Ciò significa che non è necessario preoccuparsi del passaggio di dati dannosi, poiché tutti i dati sono tradotti legalmente o sono noti per essere non validi. Codice psudoish:

@columns = qw/Name Address Telephone/;
if ($columns[$param]) {
  $query = "select * from contacts where $columns[$param] = ?";
} else {
  die "Invalid column!";
}

run_sql($query, $search);

Altri suggerimenti

Il trucco è avere fiducia nelle tue routine di fuga e convalida. Uso la mia funzione di escape SQL sovraccaricata per letterali di diversi tipi. Da nessuna parte inserisco espressioni (anziché valori letterali tra virgolette) direttamente dall'input dell'utente.

Comunque, si può fare, raccomando un & # 8212 separato; e rigoroso & # 8212; funzione per la convalida del nome della colonna. Consentiscigli di accettare solo un singolo identificatore, qualcosa come

/^\w[\w\d_]*$/

Dovrai fare affidamento su ipotesi che puoi fare sui nomi delle tue colonne.

Uso ADO.NET e l'uso dei comandi SQL e SQLParameters per quei comandi che si occupano del problema Escape. Quindi, se ci si trova anche in un ambiente con strumenti Microsoft, posso affermare che lo utilizzo in modo molto efficace per creare SQL dinamici e tuttavia proteggere i miei parametri

buona fortuna

Crea la colonna in base ai risultati di un'altra query in una tabella che elenca i possibili valori dello schema. In quella seconda query è possibile codificare la selezione sul nome della colonna utilizzata per definire lo schema. se non viene restituita alcuna riga, la colonna inserita non è valida.

In SQL standard, racchiudi gli identificatori delimitati tra virgolette doppie. Ciò significa che:

SELECT * FROM "SomeTable" WHERE "SomeColumn" = ?

selezionerà da una tabella chiamata SomeTable con la maiuscola mostrata (non una versione convertita in maiuscolo del nome) e applicherà una condizione a una colonna chiamata SomeColumn con la maiuscola mostrata.

Di per sé, non è molto utile, ma ... se puoi applicare la tecnica escape () con doppie virgolette ai nomi inseriti tramite il tuo modulo web, puoi costruire la tua query in modo ragionevolmente sicuro.

Naturalmente, hai detto che volevi evitare di usare escape - e in effetti non devi usarlo sui parametri in cui fornisci il? luogo titolari. Ma laddove stai inserendo dati forniti dall'utente nella query, devi proteggerti da persone maligne.

DBMS diversi hanno modi diversi di fornire identificatori delimitati. MS SQL Server, ad esempio, sembra utilizzare parentesi quadre [SomeTable] anziché doppie virgolette.

I nomi delle colonne in alcuni database possono contenere spazi, il che significa che dovresti citare il nome della colonna, ma se il tuo database non contiene tali colonne, esegui semplicemente il nome della colonna attraverso un'espressione regolare o una sorta di controllo prima di eseguire lo splicing in l'SQL:

if ( $column !~ /^\w+$/ ) {
  die "Bad column name [$column]";
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top