PHP ottiene la vulnerabilità del codice parametro [chiusa]

-2

Ho un URL come questo:

mywebsite.com?id=12345678

recupero id e lo passo a function in questo modo:

$id = $_GET["id"];
if(isset($id)){
  dosomething($id);
}

Sono nuovo di php e in realtà non capisco se in qualche modo il $id param possa essere sfruttato per eseguire del codice. Lo vedo solo come una stringa.

    
posta steo 03.01.2018 - 12:19
fonte

3 risposte

2

Dipende completamente da cosa dosomething fa.

Uno dei tanti potenziali attacchi è l'iniezione sql se non si disinfettano i parametri passati a sql e non si usano le istruzioni preparate.

Ad esempio, se dosomething() fa qualcosa sulla falsariga di: sql.query("SELECT * FROM users WHERE userid=$id") senza prima verificare la validità di $id , potrei semplicemente raggiungere il tuo sito web con: ID 1 OR id!=1 . A seconda di come fai con il risultato, potresti aver appena esposto la tua intera tabella utenti. Oppure potrei essere cattivo e basta: ID = 1; DROP TABLE users .

Quindi sì: dovresti convalidare tutti gli input dell'utente e del client prima di fare qualsiasi cosa con esso.

    
risposta data 03.01.2018 - 12:25
fonte
0

Dipende da cosa fa something() . In generale, non vuoi che gli utenti siano in grado di passare dati arbitrari nei tuoi script. Il tuo codice fa questo, come non controlli, se l'input dell'utente è quello che ti aspettavi che fosse.

Dicendo questo in modo astratto: Non fare mai supposizioni su ciò che ottieni!

Esempio: generi una query SQL come questa:

if(isset($_GET["id"])) {
    $sql = "SELECT * FROM table WHERE id = ".$_GET["id"].";"
    // execute SQL here
    // process results here
}

Supponiamo che tu riceva questo input da un modulo, in cui si afferma che il campo "id" deve essere riempito solo con un numero (o addirittura utilizzare l'attributo HTML5).

Utente ignaro

Questo tipo inserisce un valore non numerico, come ab"fe; e invia il modulo. La richiesta genererà un'eccezione / errore SQL in quanto la query risultante è:

SELECT * FROM table WHERE id = "ab"fe;"; SQL non valido

Ciò è avvenuto perché hai assunto, riceverai solo valori numerici, ma nulla impedisce a un utente di inviare qualcos'altro. Anche se si utilizza l'attributo HTML5, un browser degli utenti può ignorarlo o l'utente stesso crea una richiesta specifica e la invia al proprio endpoint. Diamo un'occhiata a uno scenario peggiore.

Utente dannoso

Questo tizio prova a fare casino con te e invia owned"; DROP DATABASE * dove l'istruzione SQL risultante è:

SELECT * FROM table WHERE id = "owned"; DROP DATABASE *; poof, il tuo database è scomparso ...

Generalmente vuoi sempre essere assolutamente sicuro, sai che tipo di dati stai elaborando. Utilizza metodi come is_numeric() per assicurarti che i dati contengano ciò che pensi sia fatto. Questo processo di eliminazione dei dati indesiderati e preparazione per l'utilizzo è chiamato sanitizing .

Inoltre, devi sempre escape stringhe prima di utilizzarle in un'istruzione SQL, per evitare che qualcuno inietti caratteri speciali, come "" o ; in SQL.

Il cattivo o la completa mancanza di sanificazione dei dati è un'enorme vulnerabilità, quindi fai attenzione, ogni volta che usi qualcosa che un utente ti invia. Controlla tutto sul lato server, non fidarti dei moduli JavaScript che disabilitano un pulsante "Invia", dal momento che le persone possono ancora inviare richieste elaborate al tuo server.

    
risposta data 03.01.2018 - 14:36
fonte
0

Contrariamente alla maggior parte delle risposte qui, per me la necessità non dipende da cosa dosomething() fa. Applicando la difesa in profondità, la mia linea di difesa è quella di sanificare sempre il valore che arriva dall'esterno dell'ambiente prima di fare qualsiasi altra cosa con esso. Forse sarà eccessivo, ma è meglio testare un po 'di più per maggiore sicurezza a costo di piccole prestazioni probabilmente trascurabili comunque, invece del contrario.

Quindi, dosomething() ha un'API e poiché la tua lingua non funziona per tipo di default e convalida del contenuto, dovrei controllare la variabile $id prima di iniettarla in dosomething() . Sulla base della sua API, sai che $id dovrebbe essere qualcosa di specifico, come un intero, o una stringa, o qualsiasi altra cosa. Quindi prova per questo, inclusa la lunghezza necessaria e annulla prematuramente e prima di chiamare doSomething() le cose non sono come ti aspettavi.

L'unica altra opzione sarebbe quella di eseguire gli stessi test delle primissime righe all'interno di dosomething() . Ma questo dipende se controlli quel pezzo di codice o meno. Ad esempio, se stavi usando alcune librerie, la prima azione (testare prima di chiamarla) sarebbe meglio, perché anche se la libreria verifica le cose, farlo da solo dovrebbe coprire più casi e creare meno punti deboli. p>     

risposta data 03.01.2018 - 15:40
fonte

Leggi altre domande sui tag