Domanda

Nello specifico ciò riguarda l'utilizzo di un cookie di sessione client per identificare una sessione sul server.

La risposta migliore è utilizzare la crittografia SSL/HTTPS per l'intero sito Web e avere la migliore garanzia che nessun uomo nel mezzo degli attacchi sarà in grado di annusare un cookie di sessione client esistente?

E forse la seconda soluzione migliore è utilizzare una sorta di crittografia sul valore della sessione stesso memorizzato nel cookie di sessione?

Se un utente malintenzionato ha accesso fisico a una macchina, può comunque esaminare il filesystem per recuperare un cookie di sessione valido e utilizzarlo per dirottare una sessione?

È stato utile?

Soluzione

La crittografia del valore della sessione non avrà alcun effetto.Il cookie di sessione è già un valore arbitrario, crittografarlo genererà semplicemente un altro valore arbitrario che può essere sniffato.

L'unica vera soluzione è HTTPS.Se non vuoi eseguire SSL sull'intero sito (forse hai problemi di prestazioni), potresti riuscire a farla franca proteggendo solo le aree sensibili con SSL.Per fare ciò, assicurati innanzitutto che la tua pagina di accesso sia HTTPS.Quando un utente accede, imposta un cookie sicuro (il che significa che il browser lo trasmetterà solo tramite un collegamento SSL) oltre al normale cookie di sessione.Quindi, quando un utente visita una delle tue aree "sensibili", reindirizzalo su HTTPS e verifica la presenza di quel cookie sicuro.Un utente reale lo avrà, un dirottatore di sessione no.

MODIFICARE:Questa risposta è stata originariamente scritta nel 2008.Siamo nel 2016 ormai e non c'è motivo di non avere SSL sull'intero sito.Niente più HTTP in chiaro!

Altri suggerimenti

L'SSL aiuta solo con gli attacchi di sniffing.Se un utente malintenzionato ha accesso al tuo computer, presumo che possa copiare anche il tuo cookie sicuro.

Per lo meno, assicurati che i vecchi biscotti perdano il loro valore dopo un po'.Anche un attacco di dirottamento riuscito verrà contrastato quando il cookie smetterà di funzionare.Se l'utente ha un cookie da una sessione che ha effettuato l'accesso più di un mese fa, chiedigli di reinserire la password.Assicurati che ogni volta che un utente fa clic sul collegamento "disconnetti" del tuo sito, l'UUID della vecchia sessione non potrà mai più essere utilizzato.

Non sono sicuro che questa idea funzionerà, ma ecco qui:Aggiungi un numero di serie nel cookie di sessione, magari una stringa come questa:

SessionUUID, numero di serie, data/ora corrente

Crittografa questa stringa e utilizzala come cookie di sessione.Cambia regolarmente il numero di serie, magari quando il cookie ha 5 minuti, quindi emetti nuovamente il cookie.Potresti anche ripubblicarlo ad ogni visualizzazione di pagina, se lo desideri.Sul lato server, tieni un registro dell'ultimo numero di serie che hai rilasciato per quella sessione.Se qualcuno invia un cookie con il numero di serie sbagliato significa che un utente malintenzionato potrebbe utilizzare un cookie intercettato in precedenza, quindi invalidare l'UUID della sessione e chiedere all'utente di reinserire la password e quindi emettere nuovamente un nuovo cookie.

Ricorda che il tuo utente potrebbe avere più di un computer, quindi potrebbe avere più di una sessione attiva.Non fare qualcosa che li costringa a effettuare nuovamente l'accesso ogni volta che passano da un computer all'altro.

Hai pensato di leggere un libro sulla sicurezza PHP?Altamente raccomandato.

Ho avuto molto successo con il seguente metodo per i siti non certificati SSL.

  1. Non consentire più sessioni con lo stesso account, assicurandoti di non controllarlo esclusivamente tramite l'indirizzo IP.Piuttosto controlla in base al token generato all'accesso che viene memorizzato con la sessione dell'utente nel database, nonché l'indirizzo IP, HTTP_USER_AGENT e così via

  2. L'uso di ipertestuali basati sulle relazioni genera un collegamento (ad es. http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) Il collegamento viene aggiunto con una stringa MD5 salata casuale X-BYTE (dimensione preferita), al reindirizzamento della pagina Il token generato in modo casuale corrisponde a una pagina richiesta.

    • Al momento della ricarica vengono eseguiti diversi controlli.
    • Indirizzo IP di origine
    • HTTP_USER_AGENT
    • Gettone di sessione
    • hai capito il punto.
  3. Cookie di autenticazione della sessione di breve durata.come pubblicato sopra, un cookie contenente una stringa sicura, che è uno dei riferimenti diretti alla validità delle sessioni, è una buona idea.Fallo scadere ogni x minuti, riemettendo quel token e risincronizzando la sessione con i nuovi dati.In caso di corrispondenze errate nei dati, disconnettere l'utente o chiedergli di autenticare nuovamente la sessione.

Non sono affatto un esperto in materia, ho avuto un po' di esperienza in questo particolare argomento, spero che qualcosa di questo aiuti qualcuno là fuori.

// Collect this information on every request
$aip = $_SERVER['REMOTE_ADDR'];
$bip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$agent = $_SERVER['HTTP_USER_AGENT'];
session_start();

// Do this each time the user successfully logs in.
$_SESSION['ident'] = hash("sha256", $aip . $bip . $agent);

// Do this every time the client makes a request to the server, after authenticating
$ident = hash("sha256", $aip . $bip . $agent);
if ($ident != $_SESSION['ident'])
{
    end_session();
    header("Location: login.php");
    // add some fancy pants GET/POST var headers for login.php, that lets you
    // know in the login page to notify the user of why they're being challenged
    // for login again, etc.
}

Ciò che fa è catturare informazioni "contestuali" sulla sessione dell'utente, informazioni che non dovrebbero cambiare durante la vita di una singola sessione.Un utente non si troverà davanti a un computer negli Stati Uniti e in Cina contemporaneamente, giusto?Pertanto, se l'indirizzo IP cambia improvvisamente all'interno della stessa sessione, ciò implica fortemente un tentativo di dirottamento della sessione, quindi proteggi la sessione terminando la sessione e costringendo l'utente a autenticarsi nuovamente.Ciò vanifica il tentativo di hacking e l'aggressore è inoltre costretto a effettuare il login invece di ottenere l'accesso alla sessione.Avvisa l'utente del tentativo (ajax un po'), e vola, Utente leggermente infastidito+informato e la sua sessione/informazione sarà protetta.

Inseriamo User Agent e X-FORWARDED-FOR per fare del nostro meglio per catturare l'unicità di una sessione per i sistemi dietro proxy/reti.Potresti essere in grado di utilizzare più informazioni, sentiti libero di essere creativo.

Non è al 100%, ma è dannatamente efficace.

C'è altro che puoi fare per proteggere le sessioni, farle scadere, quando un utente lascia un sito web e torna, magari forzandolo ad accedere di nuovo.Puoi rilevare un utente che se ne va e ritorna acquisendo un HTTP_REFERER vuoto (il dominio è stato digitato nella barra dell'URL) o controlla se il valore in HTTP_REFERER è uguale al tuo dominio o meno (l'utente ha fatto clic su un collegamento esterno/creato per accedere al tuo luogo).

Scadono le sessioni, non lasciare che rimangano valide indefinitamente.

Non fare affidamento sui cookie, possono essere rubati, è uno dei vettori di attacco per il dirottamento della sessione.

Prova il protocollo Secure Cookie descritto in Questo articolo di Liu, Kovacs, Huang e Gouda:

Come indicato nel documento:

Un protocollo di cookie sicuro che funziona tra un client e un server deve fornire i seguenti quattro servizi:autenticazione, riservatezza, integrità e anti-replay.

Per quanto riguarda la facilità di distribuzione:

In termini di efficienza, il nostro protocollo non comporta alcuna ricerca di database o crittografia a chiave pubblica.In termini di distribuzione, il nostro protocollo può essere facilmente distribuito su un server Web esistente e non richiede alcuna modifica alla specifica dei cookie di Internet.

In breve:è sicuro, leggero, per me funziona alla grande.

Non esiste un modo per impedire il dirottamento della sessione al 100%, ma con un qualche approccio possiamo ridurre il tempo impiegato da un utente malintenzionato per dirottare la sessione.

Metodo per prevenire il dirottamento della sessione:

1 - utilizzare sempre sessioni con certificato SSL;

2 - invia il cookie di sessione solo con httponly impostato su true (impedisce a Javascript di accedere al cookie di sessione)

2 - utilizzare l'ID di rigenerazione della sessione all'accesso e al logout (nota:non utilizzare la rigenerazione della sessione ad ogni richiesta perché se hai richieste Ajax consecutive hai la possibilità di creare più sessioni.)

3 - imposta un timeout della sessione

4: memorizza l'agente utente del browser in una variabile $_SESSION e confronta con $_SERVER['HTTP_USER_AGENT'] ad ogni richiesta

5 - imposta un cookie token e imposta la scadenza di quel cookie su 0 (fino alla chiusura del browser).Rigenera il valore del cookie per ogni richiesta. (Per la richiesta Ajax non rigenerare il cookie token).EX:

    //set a token cookie if one not exist
    if(!isset($_COOKIE['user_token'])){
                    //generate a random string for cookie value
        $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

        //set a session variable with that random string
        $_SESSION['user_token'] = $cookie_token;
        //set cookie with rand value
        setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
    }

    //set a sesison variable with request of www.example.com
    if(!isset($_SESSION['request'])){
        $_SESSION['request'] = -1;
    }
    //increment $_SESSION['request'] with 1 for each request at www.example.com
    $_SESSION['request']++;

    //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it's equal then regenerete value of token cookie if not then destroy_session
        if($_SESSION['user_token'] === $_COOKIE['user_token']){
            $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

            $_SESSION['user_token'] = $cookie_token;

            setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
        }else{
            //code for session_destroy
        }

    }

            //prevent session hijaking with browser user agent
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
      die('session hijaking - user agent');
    }

Nota:Non rigenerare il cookie token con richiesta AJAX Nota:il codice sopra è un esempio.Nota:se gli utenti si disconnettono, il token del cookie deve essere distrutto così come la sessione

6 - non è un buon approccio utilizzare l'ip dell'utente per prevenire il dirottamento della sessione perché l'ip di alcuni utenti cambia ad ogni richiesta.CHE INFLUISCONO UTENTI VALIDI

7 - Personalmente memorizzo i dati della sessione nel database, sta a te decidere quale metodo adottare

Se trovi errori nel mio approccio, correggimi.Se hai altri modi per prevenire l'hype della sessione, dimmelo.

Assicurati di non utilizzare numeri interi incrementali per gli ID di sessione.Molto meglio usare un GUID o qualche altra stringa di caratteri lunga generata casualmente.

Esistono molti modi per creare protezione contro il dirottamento della sessione, tuttavia tutti riducono la soddisfazione dell'utente o non sono sicuri.

  • Controlli IP e/o X-FORWARDED-FOR.Funzionano e sono abbastanza sicuri...ma immagina il dolore degli utenti.Arrivano in un ufficio con WiFi, ottengono un nuovo indirizzo IP e perdono la sessione.Devo effettuare nuovamente l'accesso.

  • Controlli dell'agente utente.Come sopra, è disponibile la nuova versione del browser e si perde una sessione.Inoltre, questi sono davvero facili da "hackerare".È banale per gli hacker inviare false stringhe UA.

  • token di archiviazione locale.All'accesso genera un token, memorizzalo nella memoria del browser e memorizzalo in un cookie crittografato (crittografato sul lato server).Ciò non ha effetti collaterali per l'utente (localStorage persiste attraverso gli aggiornamenti del browser).Non è così sicuro, poiché è semplicemente sicurezza attraverso l'oscurità.Inoltre potresti aggiungere qualche logica (crittografia/decrittografia) a JS per oscurarlo ulteriormente.

  • Riedizione dei cookie.Questo è probabilmente il modo giusto per farlo.Il trucco è consentire a un solo client alla volta di utilizzare un cookie.Pertanto, l'utente attivo avrà un cookie riemesso ogni ora o meno.Il vecchio cookie viene invalidato se ne viene rilasciato uno nuovo.Gli hack sono ancora possibili, ma molto più difficili da realizzare: sia l'hacker che l'utente valido si vedranno rifiutare l'accesso.

Consideriamo che in fase di login client e server possano accordarsi su un valore salt segreto.Successivamente il server fornisce un valore di conteggio con ogni aggiornamento e si aspetta che il client risponda con l'hash del (salt segreto + conteggio).Il potenziale dirottatore non ha alcun modo per ottenere questo valore segreto di sale e quindi non può generare l'hash successivo.

Per quanto ne so, l'oggetto sessione non è accessibile dal client, poiché è archiviato nel server web.Tuttavia, l'ID di sessione viene memorizzato come cookie e consente al server web di tracciare la sessione dell'utente.

Per impedire il dirottamento della sessione utilizzando l'ID sessione, è possibile memorizzare una stringa con hash all'interno dell'oggetto sessione, realizzata utilizzando una combinazione di due attributi, indirizzo remoto e porta remota, a cui è possibile accedere dal server Web all'interno dell'oggetto richiesta.Questi attributi collegano la sessione dell'utente al browser in cui l'utente ha effettuato l'accesso.

Se l'utente accede da un altro browser o da una modalità di navigazione in incognito sullo stesso sistema, l'indirizzo IP rimarrebbe lo stesso, ma la porta sarà diversa.Pertanto, quando si accede all'applicazione, all'utente verrà assegnato un ID di sessione diverso dal server web.

Di seguito è riportato il codice che ho implementato e testato copiando l'ID sessione da una sessione all'altra.Funziona abbastanza beneSe c'è una scappatoia, fammi sapere come l'hai simulata.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sessionKey = (String) session.getAttribute("sessionkey");
    String remoteAddr = request.getRemoteAddr();
    int remotePort = request.getRemotePort();
    String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort);
    if (sessionKey == null || sessionKey.isEmpty()) {
        session.setAttribute("sessionkey", sha256Hex);
        // save mapping to memory to track which user attempted
        Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort);
    } else if (!sha256Hex.equals(sessionKey)) {
        session.invalidate();
        response.getWriter().append(Application.userSessionMap.get(sessionKey));
        response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); 
        response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex));
        return;
    }
    response.getWriter().append("Valid Session\n");
}

Ho utilizzato l'algoritmo SHA-2 per eseguire l'hashing del valore utilizzando l'esempio fornito in SHA-256 Hashing a baeldung

Attendo con ansia i tuoi commenti.

Per ridurre il rischio puoi anche associare l'IP di origine alla sessione.In questo modo un utente malintenzionato deve trovarsi all'interno della stessa rete privata per poter utilizzare la sessione.

Anche il controllo delle intestazioni dei referer può essere un'opzione, ma queste vengono falsificate più facilmente.

Proteggiti da:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top