Domanda:
È una cattiva pratica utilizzare il metodo GET come nome utente / password di accesso per gli amministratori?
Amirreza Nasiri
2017-01-04 08:44:27 UTC
view on stackexchange narkive permalink

Lavoro su applicazioni web e, come sai, avere un pannello amministratore è un must nella maggior parte dei casi. Possiamo vedere che molte applicazioni web hanno una pagina di accesso specifica per gli amministratori in cui è presente un modulo (di solito il metodo POST ) che gli amministratori possono utilizzare per accedere al loro pannello.

Ma poiché i nomi dei campi sono noti, un hacker può tentare di violare le password anche se vengono implementati alcuni metodi di sicurezza.

Allora qual è il problema con una semplice chiave GET (come username) e il suo valore (come password)? Perché non viene utilizzato molto o almeno non è suggerito in molti articoli?

Per gli amministratori, le pagine di accesso user-friendly non sono realmente necessarie! I dati verranno registrati in entrambi i casi ( GET / POST ) se è presente un aggressore MiTM.

Ma utilizzando questo metodo, i campi saranno sconosciuti. per gli stessi amministratori. Ecco un esempio di codice PHP:

"category.php": (un nome di pagina senza significato)

  <? Phpif (isset ($ _ GET ['meaningless_user']) && $ _GET ['parola_significante'] == "qualcosa") {session_start (); $ _SESSION ["utente"] = "test"; header ('Posizione: category.php'); // Reindirizza alla stessa o ad un'altra pagina in modo che i parametri GET scompaiano dall'url} else {die (); // Quindi sarà come una pagina vuota}? >  
Dovresti usare HTTPS, quindi non dovresti preoccuparti di MITM.Inoltre, se non ti interessa la facilità d'uso, puoi implementare l'autenticazione HTTP di base o del certificato client, quindi non dovresti implementare l'autenticazione nell'applicazione web stessa.
Registri del server Web e registri proxy, periodo, motivi principali per POSTARE queste informazioni e non OTTENERLA.Tutto ciò che dicono jdow e tlng05 è vero, ma i log sono i primi "oops eccolo" con HTTP (S) GET.
Il tuo amministratore in qualche forum: "Ehi, ho questo problema con il pannello di amministrazione del mio sito. Puoi vederlo qui: http://example.com/category.php?catID=admin&pageNumber=hunter2
"* i campi saranno sconosciuti aspettati dagli amministratori stessi *" - Non sono sicuro di cosa intendi con questo.Sono generati dinamicamente?O stai suggerendo "? Myusername = mypassword"?Perché non puoi fare lo stesso con POST?
`POST` contro` GET` non è un *** importante *** ostacolo per gli hacker, ma aiuta.Ogni piccola cosa ... aiuta
La tua preoccupazione più grande è che stai utilizzando HTTPS o HTTP.Se utilizzi solo HTTP;POST o GET sono ugualmente aperti a MITM.Se stai proteggendo il canale (come dovresti essere), [GET è leggermente meno sicuro.] (Http://stackoverflow.com/questions/4143196/is-get-data-also-encrypted-in-https)
_Ma poiché i nomi dei campi sono noti, un hacker può tentare di violare le password anche se sono implementati alcuni metodi di sicurezza_ - Lo stesso vale per una richiesta GET convenzionale.Ma non c'è motivo per cui non puoi usare nomi di campo generati dinamicamente.memorizzare una ricerca di quale è sul server.Non aiuta in modo massiccio la sicurezza, ma renderà la vita un po 'più difficile per gli hacker.
Le richieste GET vengono archiviate in HISTORY anche sul browser web: questo è un obiettivo facile per chiunque riesca ad accedere al tuo computer anche per 15-20 secondi ..
E l'inserimento di nome utente e password in una richiesta GET potrebbe renderli visibili nella barra degli indirizzi del browser, a seconda della lunghezza dell'URL, il che potrebbe essere un problema se qualcuno fosse abbastanza vicino da vedere lo schermo.
Perché non utilizzare il metodo di autorizzazione che abbiamo già negli URL?`https: // utente: [email protected] /`.In questo modo, puoi collegarti a qualcosa che richiede l'autenticazione, ma il processo di autenticazione in realtà viene eseguito tramite le intestazioni della richiesta e in genere non viene visualizzato in un registro.
`nomi di campo sono noti`: non importa a meno che tu non stia usando password deboli.`admin non ha bisogno di un login user-friendly`: Quindi, imposta semplicemente l'autenticazione tramite il tuo server web (es. apache).È possibile utilizzare l'autenticazione di base e memorizzare le password nel browser (utilizzando la chiave master) o installare i certificati client sui browser (non sono necessarie password).In ogni caso, è molto più sicuro rispetto all'utilizzo di GET.
Se ti interessano le specifiche, le specifiche http consiglia vivamente di utilizzare le variabili GET solo per il recupero, non per modificare lo stato dell'applicazione.A parte le considerazioni di sicurezza alla base di questo, _può_ essere un fattore se il codice deve essere certificato per qualcosa di ISO o simili che richiedono conformità agli standard.
GET è altamente suscettibile a [cross site request forgery] (https://en.wikipedia.org/wiki/Cross-site_request_forgery) ad es.tramite immagini.Sebbene non sia ovvio per me come qualcuno possa trarne vantaggio, è meglio evitare qualsiasi azione che produca un risultato sul server (in questo caso l'accesso) tramite un GET.Non sapere come qualcosa possa essere un vettore di attacco non significa che non lo sia.Evita approcci problematici che vanno contro l'RFC.
Nove risposte:
#1
+137
jdow
2017-01-04 09:29:50 UTC
view on stackexchange narkive permalink

Ciò memorizzerebbe il collegamento di accesso con password e nome utente nella cronologia del browser. Potrebbe anche essere catturato accidentalmente da cose come i log del firewall, che non catturerebbero le variabili dei post.

Inoltre, le persone passano URL con parametri dappertutto (immagina la tua query, con i parametri nome utente e password, che appare su stackexchange).Questo potrebbe anche aprirti ad attacchi CSRF.
E anche se stai utilizzando HTTPS, ci sono ancora molte estensioni del browser che raccolgono l'URL completo della pagina che stai visitando.[WOT] (https://lifehacker.com/web-of-trust-sells-your-browsing-history-uninstall-it-1788667989) è un esempio recente che ha avuto molta pubblicità, ma ce ne sono e sono stati altri.
Ricordo un sito che ha eseguito una corretta autenticazione, ma poi ha generato una chiave di sessione che ha incorporato (stile GET) nell'URL.Era piuttosto incline a questa condivisione di URL, perché più persone notano `? User = me & password = letmein` ma`? Sess = 012345678` è meno evidentemente un problema.
Se utilizzi Google Chrome, la tua cronologia di navigazione viene inviata anche a Google per impostazione predefinita.
#2
+63
tlng05
2017-01-04 09:51:04 UTC
view on stackexchange narkive permalink

Mi vengono in mente diversi motivi per cui questo non sarebbe l'ideale:

  • Nello snippet di codice che hai pubblicato, ora stai codificando una chiave segreta nel codice sorgente del tuo programma. Questo è un male perché ora se vuoi pubblicare o condividere il tuo codice sorgente con qualcun altro, dovrai ricordarti di oscurare quella chiave. La sicurezza di un sistema non dovrebbe dipendere dal fatto che il suo codice sorgente rimanga nascosto.
  • Questo non si adatta bene. Se si dispone di una sola chiave segreta che tutti gli amministratori devono condividere, diventa molto più facile perdere accidentalmente. Se dovesse fuoriuscire, non avresti modo di sapere chi era responsabile della fuoriuscita. Potresti fornire una chiave diversa a ciascun amministratore, ma questo diventa complicato molto rapidamente.
  • Non puoi cambiare la chiave facilmente. In generale, probabilmente avrai bisogno di amministratori di sito che non sono anche operatori di server. Ma con questa configurazione, non puoi concedere a nessuno la possibilità di modificare la chiave senza concedere anche l'accesso al codice sorgente e al server, che possono o meno sapere come utilizzare handle. Modificare il codice sorgente in esecuzione su un sistema di produzione, volenti o nolenti, è soggetto a errori e probabilmente si tradurrà in tempi di inattività.
  • Poiché utilizzi GET, è molto facile che la chiave trapeli attraverso le cronologie del browser o accidentalmente condivisione di link.
  • Non è molto facile da usare. L'utilizzo di questo richiede sapere come manipolare manualmente un parametro GET specifico. Dici che la facilità d'uso per gli amministratori non è necessaria, ma questo non è assolutamente vero in generale. L'intero sito dovrebbe essere il più user-friendly possibile, compreso il pannello dell'amministratore.

In sintesi, posso vedere questo tipo di sistema in uso come misura temporanea su un piccolo sito, dove c'è un amministratore del sito che ha anche scritto il codice sorgente del sito e gestisce il server. Ma qualsiasi cosa più grande di questo, ti consigliamo di avere un vero pannello di accesso dell'amministratore, con credenziali sottoposte a hashing e salate memorizzate nel database come qualsiasi altro utente.

Per quanto riguarda il punto 2: dare chiavi diverse a ciascun amministratore non è poi così complicato.La condivisione dei segreti è in realtà piuttosto semplice.
@Mego Intendevo principalmente disordinato in termini di codice.ad esempio, cosa succede quando si desidera assegnare diversi livelli di privilegio o aggiungere / rimuovere amministratori.Questo porta anche al terzo punto.
#3
+28
AbraCadaver
2017-01-04 20:42:06 UTC
view on stackexchange narkive permalink

Non strettamente dal punto di vista della sicurezza, ma Hypertext Transfer Protocol - HTTP / 1.1 RFC 2616 lo rende abbastanza chiaro:

... la convenzione è stata stabilito che i metodi GET e HEAD NON DOVREBBERO avere il significato di intraprendere un'azione diversa dal recupero . Questi metodi dovrebbero essere considerati "sicuri". Ciò consente ai programmi utente di rappresentare altri metodi, come POST, PUT e DELETE, in un modo speciale, in modo che l'utente sia informato del fatto che viene richiesta un'azione possibilmente non sicura.

GET dovrebbe essere usato solo per il recupero. Nel tuo caso, stai inviando dati al server, il server sta eseguendo queste azioni specifiche (come minimo):

  • Autenticazione di un utente
  • Creazione di una sessione da monitorare stato utente (PHP crea i dati di sessione in file flat o in un database)
  • Impostazione di un cookie di sessione per monitorare la sessione

POST su HTTPS sarebbe il metodo preferito per la trasmissione dati sensibili; nome utente, password in questo caso.

Le operazioni GET dovrebbero essere idempotenti, il che significa che puoi eseguire l'operazione più e più volte in modo sicuro.In altre parole, non stai * cambiando * nulla sul server ... stai semplicemente fornendo i dati necessari per richiedere una risorsa specifica (in questo caso, una pagina autenticata).Per qualsiasi cosa diversa da un sito HTML statico, una richiesta GET eseguirà quasi sempre azioni significative (ad es. Www.mystore.com/product.php?productid=123 deve ancora creare e visualizzare la pagina del prodotto).L'utilizzo di GET per i dati sensibili è davvero una pessima idea, ma non necessariamente a causa della RFC 2616.
@DVK: È un'ottima ragione, anche se ce ne sono altre delineate in altre risposte.Quando si accede e si avvia una sessione (in PHP) ci sono diverse modifiche sul server e la sessione è persistente tra le pagine.
Le operazioni GET di @DVK non dovrebbero essere solo idempotenti, dovrebbero essere pure (che penso sia ciò che intendevi).Essere idempotenti significa farlo due volte ha gli stessi effetti collaterali di farlo una volta.Essere puro significa farlo una volta ha gli stessi effetti collaterali di non farlo affatto.Per confronto, DELETE è idempotente, ma non puro.
@James_pic "Essere puri significa farlo una volta ha gli stessi effetti collaterali che non farlo affatto."Quando parliamo di significato, parliamo di risorse, non dell'invocazione di processi lato server necessari per recuperare la risorsa.L'accesso non ha davvero effetti collaterali in termini di risorse.Non crea, elimina o modifica una risorsa.Fornisce i dati necessari (in questo caso, le informazioni di autenticazione) per individuare e visualizzare la risorsa, non diversamente da? Productid = 123.La differenza principale è che l'RFC specifica che le informazioni sensibili NON devono essere in GET.
@AbraCadaver Praticamente qualsiasi sito dinamico invocerà modifiche sul server per qualsiasi richiesta, indipendentemente dal fatto che ti autentichi o meno.L'importanza è che non stai facendo nulla con le risorse sottostanti stesse.Qualsiasi modifica sul lato server è semplicemente incidentale per la visualizzazione della risorsa.Un utente che accede o non accede (o accede 9 volte) generalmente non ha alcun impatto sulle risorse a cui sta tentando di accedere, quindi direi che l'accesso è puro (sicuro).Se la creazione di una sessione preclude l'utilizzo di GET, GET potrebbe essere utilizzato fondamentalmente solo per le risorse statiche.
@DVK: In chiusura, ** NON DOVREBBE ** e ** a parte il recupero ** sembrano piuttosto semplici.Quando si accede, lo stato dell'azione cambia da non autenticato ad autenticato e può essere concesso l'accesso a dati e / o azioni aggiuntivi.
La regola non è che GET non dovrebbe fare nulla alle risorse.La regola è che GET non dovrebbe essere inteso come una richiesta da parte del client di fare qualcosa - tutto ciò che accade accade perché il server ha deciso di volerlo fare e il client non dovrebbe essere responsabile di ciò.
#4
+26
Andy Holland
2017-01-04 17:40:34 UTC
view on stackexchange narkive permalink

Quanto sei a tuo agio con l'archiviazione delle password di amministratore in testo non crittografato nei log di accesso del tuo server web?

Il problema che vedo qui è che una richiesta GET deve inserire tutti i nomi di campo e valori nell'URI della richiesta. Gli URI delle richieste vengono registrati da tutti i tipi di processi e probabilmente verranno archiviati, per intero, nel registro di accesso al server web.

Ciò significa che il tuo registro di accesso al server web aumenta il rischio per la sicurezza perché ora contiene i nomi utente e le password per le pagine di accesso basate su GET. Sebbene in genere si possa trattare i log del server come contenenti informazioni privilegiate (ad esempio gli IP del cliente), in genere non sono così sensibili da contenere informazioni sufficienti per compromettere l'interfaccia amministrativa di un client.

POST è superiore per questo, perché i nomi e i valori dei campi non vengono memorizzati nel registro.

#5
+4
Machavity
2017-01-05 00:04:25 UTC
view on stackexchange narkive permalink

Un utente malintenzionato ottiene le credenziali di amministratore. Utilizzo di un tag immagine

  <img src = "https://example.com/login?username=admin&amp;password=topsecret" style = "display: none" >  

ingannano il tuo browser per accedere (le immagini non sono soggette a restrizioni interdominio per impostazione predefinita). Possono quindi utilizzare una serie di chiamate "immagine" per ottenere o modificare dati (molte chiamate AJAX utilizzano anche GET in modo errato). Esistono modi per evitarlo, ma la maggior parte delle persone non li abilita. Se stai utilizzando POST, questo vettore di attacco non funziona.

La chiave del campo è sconosciuta, come può indovinarlo un attaccante?
Come è stato accennato altrove, è possibile ottenerlo da un browser o potrebbe essere condiviso da un utente.La sicurezza attraverso l'oscurità dura solo finché ai tuoi utenti interessa.
@AmirrezaNasiri se esiste un modulo di accesso visibile pubblicamente che utilizza GET, come può il nome del campo della password essere sconosciuto?
Penso che @AmirrezaNasiri stia suggerendo che non ci sarebbe un modulo visibile, invece gli amministratori saprebbero semplicemente come digitare get parameters nella barra degli indirizzi.
#6
+3
Lucas
2017-01-04 18:11:21 UTC
view on stackexchange narkive permalink

Il problema dell'utilizzo del metodo get è che i dati saranno visibili sullo schermo e nei log del server web per impostazione predefinita.

La mia regola pratica è utilizzare post per password e grandi informazioni come l'articolo del blog editor e usa get per quasi tutto il resto. Ovviamente ci sono alcune eccezioni in cui i dati sono troppo sensibili per apparire anche nei log. Ma quelli sono rari anche nel settore aziendale.

Ad esempio, ho una funzionalità simile a una procedura guidata con 5 passaggi in cui genero un ID di processo sul primo passaggio e ad ogni passaggio vedrai ? proc_id = 123 . PHP supporta la stringa di query anche nei metodi di post. Anche in un passaggio in cui i dati del modulo sono troppo grandi e sono costretto a utilizzare il metodo post, l'id del processo è ancora visibile nell'URL come ?proc_id=123.

Questo rende più facile inserire i segnalibri, più facile capire i log di accesso, nonché più educativo per le terze parti che vogliono integrarsi con le mie app.

Alcune precauzioni devono essere prese in questo scenario per evitare problemi con il pulsante indietro come la cancellazione dagli URL della cronologia che non devono essere reinviati. La maggior parte delle azioni di salvataggio sono così.

Ovviamente il POST non ti proteggerà da un attacco MiTM. Impedirà solo che informazioni sensibili come password vengano scritte nei log del tuo sito e nella cronologia locale del browser.

#7
+3
Andre Geddert
2017-01-04 22:04:00 UTC
view on stackexchange narkive permalink

Considera anche che le richieste GET hanno lo scopo di non modificare nulla sul lato server. Un cambio di stato come "disconnesso" -> "connesso" deve sempre essere eseguito con una richiesta POST.

Avere un parametro GET come

  https: / /example.com/loginpage.php?password=topsecret 

è semanticamente esattamente uguale a

  https://example.com/loginpage/password / topsecret 

Quindi non c'è alcuna autenticazione. È solo un URL "segreto" che devi conoscere per "accedere".

Per renderlo più chiaro. Se usi Apache, ad esempio, puoi ottenere lo stesso risultato con un reindirizzamento come questo:

 RedirectTemp password / topsecret veryobfuscateddirectoryname / loggato 

e poi nella pagina di login inserisci il tuo session_start ()

#8
+2
Leo Wilson
2017-01-07 21:55:20 UTC
view on stackexchange narkive permalink

Anche se l'utente e la password non sono stati memorizzati nella cronologia del browser (quali sono, come parametri URL), questo rende estremamente facile per qualsiasi hacker rubare le tue informazioni. Apparirà nei log del server, rende ancora più facile eseguire un attacco man-in-the-middle. Permette anche molte cattive pratiche, come le persone che aggiungono ai segnalibri l'URL di accesso, se ne dimenticano e consentono ad altri utenti di utilizzare il proprio browser Web.

TL; DR: Questa è un'idea orribile.

#9
+1
bdsl
2017-01-07 05:44:37 UTC
view on stackexchange narkive permalink

Sì, è una cattiva pratica. Qualsiasi vantaggio di sicurezza disponibile avendo un nome di campo segreto può essere ottenuto anche anteponendo quel segreto alla password.

Invece di GET con

  elephant = rthg4e5sdc  

sarebbe meglio usare POST con

  password = elephantrthg4e5sdc  

E ovviamente puoi aumentare di nuovo la sicurezza cambiandolo in qualcosa di più simile

  password = ehu3dva7rthg4e5sdc  


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...