Come validare correttamente i dati da $_GET o $_REQUEST utilizzando le funzioni di WordPress?

12 set 2012, 19:17:16
Visualizzazioni: 18.7K
Voti: 8

Sto lavorando a un plugin che richiede la manipolazione dinamica dell'output dei contenuti. Questo dipende esclusivamente dalla variabile $_GET corrente o dalla variabile $_REQUEST.

A seconda di come è impostata la variabile, verrà chiamato un determinato metodo della classe per gestire la richiesta dell'utente e visualizzare il contenuto appropriato.

Sono pienamente consapevole della pagina Validazione dei Dati sul Codex di WordPress, tuttavia non sono sicuro di quale sia l'approccio migliore per il mio scenario, o per qualsiasi scenario di sanitizzazione delle variabili $_GET o $_REQUEST.

Come posso sanitizzare utilizzando le funzioni di WordPress per una variabile $_GET o $_REQUEST quando si tratta di una stringa che verrà confrontata per chiamare un metodo specifico di una classe?

Questo codice potrebbe essere sfruttato o fallire nelle seguenti condizioni?:

public function display_admin_page(){
    if(is_admin() && isset($_GET['page'])){
        global $content;
        $page = sanitize_title($_GET['page']);
        $method_name = 'page_'.str_replace('-', '_', $page);
        if(method_exists('content', $method_name)){
            // Visualizza la pagina richiesta dalla classe content
            $thePage = $content->$method_name();
        } else{
            $thePage = $content->error(404);    
        }
        echo $thePage;
    }
}
0
Tutte le risposte alla domanda 4
1

WordPress non fornisce funzioni specifiche per la validazione dei dati nei SUPERGLOBAL.

Utilizzo la funzione PHP filter_input e poi la proteggo come farei con qualsiasi variabile non attendibile.

$url = filter_input( INPUT_GET, 'some_query_string', FILTER_VALIDATE_URL );

echo '<a href="'. esc_url( $url ). '">Cliccami</a>';

La funzione filter_input di PHP accetta:

12 set 2012 19:33:57
Commenti

@Chris_0, e per le richieste $_GET? Ad esempio, filter_var( $_GET[ $item['name'] ], FILTER_SANITIZE_FULL_SPECIAL_CHARS ). Dovrebbe essere implementato in modo diverso?

Motivated Motivated
30 ott 2022 10:12:17
2

Per il tuo esempio specifico:

Hai sanificato i dati $_GET appropriatamente (anche se io userei sanitize_key invece di sanitize_title -- non c'è molta differenza, ma sanitize_title è pensato per l'uso negli URL).

La funzione method_exists restituirà true anche per i metodi privati e protetti, quindi se un utente cerca di chiamare un metodo privato o protetto, fallirà senza arrivare al 404. (A meno che il metodo display_admin_page non sia nella stessa classe.)

Questo ci porta alla principale potenziale vulnerabilità: chiunque può forzare l'esecuzione di qualsiasi metodo pubblico nella tua classe. Se possibile, è sempre meglio specificare una whitelist di ciò che può essere accettato. In questo modo potresti validare con qualcosa come:

if ( !in_array( $_GET['page'], array( 'accepted_method', 'another_accepted_method' ) ) )
     $content->error(404);
12 set 2012 22:22:47
Commenti

Potresti gentilmente elaborare ulteriormente la teoria del potenziale exploit?

Michael Ecklund Michael Ecklund
13 set 2012 17:15:11

Certo, intendo dire che è qualcosa che devi semplicemente analizzare a fondo. Ogni metodo pubblico nella tua classe può essere forzato a essere eseguito da chiunque in qualsiasi momento. Questo non è automaticamente un exploit, ma è una considerazione da fare. C'è un metodo nella tua classe che elimina dal tuo database? C'è un metodo che stampa le password dei tuoi utenti? Aggiungerai mai altri metodi di cui dovrai preoccuparti? Ecc.

SeventhSteel SeventhSteel
14 set 2012 16:23:01
2

Consiglio di utilizzare mysql_real_escape_string($_GET) su qualsiasi richiesta GET. È una funzionalità PHP molto potente.

Successivamente puoi utilizzare str_replace() per sostituire qualsiasi carattere indesiderato.

AGGIORNAMENTO 2023:

esc_sql() è la soluzione perfetta.

12 set 2012 19:26:06
Commenti

La funzione WordPress esc_sql() non è una scelta migliore?

gillespieza gillespieza
10 feb 2023 12:55:04

@gillespieza naturalmente lo è, ma nel 2012 quella funzione era migliore. È una risposta di 11 anni fa :)

Ciprian Ciprian
10 feb 2023 15:17:58
0

La sanificazione di $_GET è piuttosto specifica al contesto. Dipende dal valore che desideri e da come vuoi che venga validato.

Non esiste una risposta universale a questa domanda. È molto specifica al contesto. Ad esempio, potresti scrivere una funzione che rimuove tutti i tag e gli slash dall'input, il che è molto sicuro, ma cosa succede se volessi salvare un tag p? Nessun problema lì. La famiglia di funzioni wp_kses() è uno studio interessante, ma non è una grande soluzione, poiché tiene conto del contesto, del livello dell'utente e altro ancora. Ad esempio, come amministratore puoi salvare JavaScript nel titolo e nel contenuto del post, ma con un ruolo inferiore non puoi.

Se il valore è una quantità nota, puoi anche verificare se in_array( $array_valid_strings ) ed essere sicuro al riguardo.

Detto questo, ci sono diversi gradi di sanificazione, quindi è importante tenere a mente il tuo obiettivo finale. Consulterei questa lista e troverei la funzione o la combinazione di funzioni che si adatta alle tue esigenze. Sono specificamente le funzioni sanitize_ quelle che dovrebbero essere utilizzate qui, non esc_. La sanificazione e l'escape continuano a essere confusi...

Nel mio caso utilizzerò sanitize_text_field() perché sanifica una stringa dall'input dell'utente o dal database.

  • Verifica la presenza di UTF-8 non valido,
  • Converte i singoli caratteri < in entità
  • Rimuove tutti i tag
  • Rimuove le interruzioni di riga, le tabulazioni e gli spazi extra
  • Rimuove gli ottetti

Buona fortuna :).

P.S. Questa risposta cita le prospettive di tre diversi sviluppatori (Josh, Michal, Kevin).

11 ott 2016 21:19:29