it-swarm.dev

C'è una differenza tra GET e POST per la sicurezza delle applicazioni web?

Ho 2 opzioni per l'invio di dati tra 2 applicazioni Web.

  1. Codifico i dati in Base64 e li accludo all'URL e recupero questi parametri nella mia applicazione di destinazione e decodifica i parametri.

    Ad esempio, http:/myDomain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

  2. Invia i parametri come valori nascosti da application1 a application2.

    String res = (String) request.getAttribute ("paramValue"); 
     Document.myForm.action = 'myDestinationURL'; 
     Document.myForm.method = "POST"; 
     document.myForm.submit (); 
     
     <form name = "myForm" method = "post"> 
     <input type = "hidden" name = "paramValue" value = "<% = res%>" />

Nella scelta 1, si possono conoscere i parametri che sto inviando e la mia tecnica di codifica. Nella scelta 2, è possibile visualizzare i dati che sto inviando facendo facilmente una vista sorgente.

A parte quanto sopra, quali sono i modi possibili per un intruso di conoscere meglio il mio sistema? E quale opzione è più adatta in generale per uno sviluppatore? Scelta 1 o Scelta 2?

41
Vikas V

L'opzione 1 può comunque introdurre una serie di problemi non legati alla sicurezza:

  • L'URL risultante può essere memorizzato nella cache dal browser o aggiunto ai segnalibri, causando il reinvio degli utenti.
  • L'URL risultante può essere condiviso dagli utenti, causando l'invio da parte di terzi.
  • L'URL può essere inviato a il tuo fornitore del browser , che può visitare il sito.

Ma si tratta di sicurezza e introduce alcuni rischi non presenti nell'opzione 2:

  • L'URL con il suo parametro potrebbe finire nei registri proxy di tutto il percorso, rivelando i tuoi dati.
  • La tua funzione di decodifica è ora un vettore di attacco aggiuntivo. (Gestisce correttamente Unicode? Ha limiti di lunghezza?)
  • Potresti essere tentato di pensare alla tua stringa codificata come in qualche modo sicura, quando è solo sicurezza attraverso l'oscurità (e non molta oscurità), o forse più appropriatamente, teatro della sicurezza .

Detto questo però; altrimenti sono ampiamente equivalenti nella sicurezza che offrono. Entrambi inviano dati di testo semplice nell'intestazione HTTP e base64 non è esattamente scienza missilistica (e puoi base64 codificare il tuo POST).

Nessuno dei due offre alcuna protezione significativa per i tuoi dati.

Se si tratta di informazioni che l'utente non desidera vedere; perché lo stai inviando all'utente per cominciare? Considera l'architettura che stai utilizzando e verifica se esiste un modo per rimuovere completamente il rischio non gestendo tali informazioni sul lato client.

Quindi, per rispondere alla domanda: per quanto riguarda l'invio di dati - entrambi rivelano le stesse informazioni a un utente malintenzionato; scegli quale opzione è più appropriata per la situazione ( questo post sul blog Treehouse può aiutarti in questo ), ma non dovresti fare affidamento su entrambi i metodi per proteggere effettivamente qualsiasi cosa.

43
Bob Watson

È facile effettuare richieste GET tra siti includendo un semplice <img> tag in una pagina Web. Ad esempio, in una pagina di www.evilhacker.com, alcuni Javascript producono un lungo flusso di <img> tag con percorsi scelti dall'aggressore, tutti puntati su www.targetbank.com - e il tuo browser includerà il cookie della banca in tutte le richieste.

Questo da solo significa che sarebbe meglio non supportare GET richieste che implicano qualsiasi modifica sul sito di destinazione. Come regola generale, le richieste GET dovrebbero essere riservate alle operazioni per le quali ripeti gli attacchi non sono un problema - vale a dire, in pratica, gli accessi in lettura ai dati statici con .

15
Thomas Pornin

Utilizzare POST per inviare richieste che modificano i dati sul server.

Con specifica HTTP , le richieste GET (ad es. Parametri nell'URL) devono essere utilizzate solo per le richieste da recuperare (da qui il nome GET) ma non modificare i dati. POST (parametri non visibili, ma ancora non crittografati nella richiesta HTTP) dovrebbero essere utilizzati ogni volta che la richiesta crea/aggiorna/modifica i dati che devono essere memorizzati nel database (diversi dai registri standard) Ciò rende leggermente più difficile per gli autori di attacchi eseguire falsi di richieste tra siti, nonché meno probabilità di inviare o archiviare accidentalmente informazioni segrete nella cronologia della pagina Web/nei registri del server Web.

La variabile pin è un segreto?

Quello che stai facendo al momento sembra che potrebbe non essere sicuro a seconda del significato della variabile pin. Questo deve essere tenuto segreto da potenziali intercettatori o le persone che intercettano il perno possono fare una specie di attacco con esso? In tal caso, utilizzare solo HTTPS (per la crittografia end-to-end sul livello di trasporto) per ogni richiesta con questi dati segreti. Il valore base-64 che hai usato sembra essere 3000670269 (Ammesso che ho dovuto aggiungere due segni uguali per renderlo una codifica b64 corretta).

Cosa succederebbe se un attaccante provasse a usare altri pin?

Diciamo il mio pin='300670269', Ma per testare il tuo sistema ho inviato MzAwMDY3MDI1OQ (Per pin='3000670259'). Ciò consentirebbe loro di entrare effettivamente in un altro account utente? In tal caso, almeno, dovresti fare qualcosa come avere una variabile extra POST come checksum=SHA256(pin+secret_server_side_string) dove secret_server_side_string È una lunga stringa casuale (ad es. qualcosa come de10RRORX50UAUhx0dDIxJnzXKBAs68yjdWVz8QQ - 40 casuali superiore + inferiore + numeri i caratteri hanno lg (62) * 40 = 238 bit di entropia) e le tue applicazioni agiscono sul pin solo se il checksum corrisponde pin. La tua applicazione dovrebbe generare il checksum (senza rivelare secret_server_side_string al client). Inoltre, devi fare attenzione che l'applicazione esegua confronti di stringhe a tempo costante quando controlla il checksum con il pin, quindi la tua applicazione non è vulnerabile a attacchi temporali.

11
dr jimbob

Oltre alla risposta di Bob, c'è un altro svantaggio di sicurezza quando si utilizzano le richieste GET con parametri sensibili.

L'URL, che include le informazioni riservate, viene inviato a server Web di terze parti che ospitano risorse a cui fa riferimento la pagina HTML risultante.

Esempio:

Prima richiesta:

GET /someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ HTTP/1.0
Host: domain

Risposta a tale richiesta:

HTTP/1.0 OK
Content-type: text/html

<img src="http://thirdparty/hello.jpg" />

Il browser web esegue il rendering dell'HTML e cerca di ottenere l'immagine come segue:

GET /hello.jpg HTTP/1.0
Host: thirdparty
Referer: http://domain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

Questo può essere particolarmente un problema quando l'HTML renderizzato nella pagina è controllato dall'aggressore (in una certa misura, avendo html nella whitelist). Ad esempio, un servizio di posta Web che inserisce la sessione nell'URL consentirebbe agli aggressori di inviare un'immagine nel corpo HTML dell'email che punta al server/script Web dell'aggressore. Quindi l'attaccante deve semplicemente seguire l'URL nell'intestazione Referer inviata dal browser Web della vittima durante il rendering dell'immagine. Questo tipo di vulnerabilità ha in effetti influenzato la posta di Excite (stiamo parlando della storia qui :)) e alcuni altri servizi di webmail in passato.

3
Sandro Gauci

Esiste un recente attacco interessante che è stato sfruttato per eludere le regole del firewall delle applicazioni Web note come " HTTP Polleter Pollution attack ". Spiegherò con un esempio simile

POST /index.aspx?par=1&par=2 HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Cookie: par=5; par=6
Content-Length: 19
par=3&par=4 

Per questa richiesta post comportamento dell'applicazione dipenderà dallo sviluppatore e come per Java.

  1. javax.servlet.ServletRequestInterface (analisi diretta della stringa di query)
  2. Java.lang.StringgetParameter (Java.lang.Stringname) Restituisce il valore di un parametro di richiesta come String o null se il parametro non esiste
  3. Java.lang.String [] getParameterValues ​​(Java.lang.Stringname) Restituisce una matrice di oggetti String contenente tutti i valori del parametro di richiesta dato, oppure null se il parametro non esiste.
3
Ali Ahmad

Un altro fattore di sicurezza da considerare è che i log di accesso del server Web acquisiscono in genere gli URL richiesti, inclusi i parametri della stringa di query. Se non si desidera registrare la stringa di query, potrebbe essere necessario ricorrere a una richiesta POST.

Ci sono, ovviamente, fattori non legati alla sicurezza da considerare quando si decide tra GET e POST, come il comportamento del browser quando si ricarica la pagina o quando la pagina viene richiamata tramite il browser Tasto indietro.

0
200_success