2010-11-12 7 views
4

Scénario:La session PHP var assez pour l'utilisateur?

  • Une fois qu'un utilisateur a ouvert une session, une variable de session est définie confirmant leur connexion.
  • En haut de chaque page, la variable de session de connexion est confirmée valide
  • Si ce n'est pas le cas, ils sont démarrés.
  • Aucun cookies persistants sont utilisés, seuls session

Question:

Est-ce une assez forte mesure de sécurité par lui-même, ou devrais-je

  • Définissez deux variables de session pour eachother valider et/ou
  • Validation de la base de données d'implémentation/de hachage
  • ...?

========

(Soit dit en passant, alors que je faisais des recherches sur cette question, this wiki est une lecture fantastique.)

Répondre

6

Il suffit de simplement stocker connexion de l'utilisateur (ou un utilisateur id) dans la session.

Pour éviter tout fixation/détournement session que vous avez besoin est juste de mettre en œuvre algorythme simple (pseudo-code):

if (!isset($_SESSION['hash']) { 
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'); 
} else if ($_SESSION['hash'] != md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua')) { 
    session_regenerate_id(); 
    $_SESSION = array(); 
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'); 
} 

Vous pouvez déplacer le calcul de hachage dans une fonction pour éviter la duplication, je viens de vous montrer un croquis de protection possible.

Voilà comment je mis en œuvre ce type de protection dans ma classe de session kohana:

abstract class Session extends Kohana_Session 
{ 
    public function read($id = null) 
    { 
     parent::read($id); 

     $hash = $this->calculateHash(); 
     $sessionHash = $this->get('session_fixation'); 

     if (!$sessionHash) { 
      $this->set('session_fixation', $hash); 
     } elseif ($sessionHash != $hash) { 
      $this->regenerate(); 
      $_SESSION = array(); 
      $this->set('session_fixation', $hash); 
     } 
    } 

    private function calculateHash() 
    { 
     $ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1'; 
     $ua = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'; 
     $charset = !empty($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : 'no charset'; 
     $ip = substr($ip, 0, strrpos($ip, '.') - 1); 
     return md5($ua . $ip . $charset); 
    } 
} 
+0

A propos d'accepter, mais désolé, mais je me sens comme je l'ai besoin de plus. Une référence ou deux, quelques arguments concernant l'usurpation/piratage ... il me semble faible d'utiliser une seule variable pour toute la procédure d'authentification. – Ben

+0

Détournement de quoi ?! Session est une donnée entièrement stockée sur le serveur. – zerkms

+0

@Steve: Je viens de demander spécifiquement sur votre question spécifique "Est-ce une mesure de sécurité assez forte en soi". Un autre commentaire avec un lien vers 'shiflett.org' a plusieurs conseils ** inutiles **. L'auteur n'a parfois aucune idée de quoi il parle. – zerkms

2

Ne pas essayer d'écrire votre propre système de session, PHP fera mieux.

oui vous pouvez ajouter plus d'informations à votre _SESSION $ pour aider à prévenir le détournement de session

par exemple, je produis une empreinte digitale en combinant une phrase secrète ou des données aléatoires avec l'agent utilisateur et le session_id() et le haschisch tout . Pour pirater une session, l'utilisateur doit trouver un id_session valide et le hachage de l'empreinte digitale. Il ressemblera à ceci. This is a good read

$_SESSION['fingerprint'] = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());

vous validerait la session comme

$check_print = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id()); 

if($check_print != $_SESSION['fingerprint'] || $_SESSION['authenticated']){ 
    //invalid session 
} 
+0

Merci pour le lien! – Woppi

+0

Quel est le rôle de la chaîne 'somethingSecret' ici et pourquoi avez-vous besoin de 'session_id()' dans l'empreinte digitale? – zerkms

+0

Je recommande de lire cet article que j'ai posté, mais disons que certains utilisateurs malveillants trouvent un session_id actif et l'envoie au serveur pour tenter d'accéder à un compte, il devrait également présenter le hash d'empreinte digitale qui serait pratiquement impossible pour deviner, il devrait savoir A) la chaîne secrète B) le navigateur que l'utilisateur légitime utilisait et C) le session_id et devrait savoir utiliser un hachage md5 et présenter cela dans le cadre de la session. – Brian

0

En date du 15 Novembre, les deux réponses que j'ai reçues ne traitent pas ma question, qui était

« Est-ce cette [une seule variable de session] une mesure de sécurité assez forte par elle-même?"

This question dit oui, mais il semble y avoir une certaine dissension Voici un résumé des différents résultats:..

1) Une variable de session unique ne suffit pas de sécurité depuis une session can be hijacked fairly easily

2) Comme cela peut se produire, aucune session n'est vraiment sûre, mais elle peut être sécurisée grâce à l'ajout d'une empreinte digitale, ce qui garantit une vérification unique et répétable chaque fois qu'une session a besoin d'être validée. User-Agent et quelques autres (voir son code)

3) Salting the fingerprint est généralement inutile car il obscurcit les données mais est répliqué sur chaque machine client, perdant ainsi son caractère unique.

4) Une solution de base de données est inutile car il s'agit d'un problème côté client.

Pas la réponse définitive que je cherchais, mais je suppose que cela devra faire, faute de mieux.

lecture qui a aidé/me confondre plus:

Session hijacking and PHP

Is HTTPS the only defense against Session Hijacking in an open network?

1

Il n'y a rien que vous pouvez faire, sauf HTTPS utilisation.

Peu importe le nombre de cookies que vous ajoutez ou quelles données vous avez hachées; Tout peut être reniflé et renvoyé au serveur.

Si vous voulez forcer un utilisateur à utiliser un seul UA tout au long de la durée de sa requête, cela peut vous aider: vous n'avez pas besoin d'une activité de hachage spéciale, car vous le hachez en $_SESSION l'utilisateur ou le pirate de l'air peut accéder directement, alors pourquoi s'embêter à le hacher? Pourrait aussi bien stocker $_SESSION["reportedUA"] = $_SERVER["HTTP_USER_AGENT"] sur la connexion, puis vérifier reportedUA sur chaque demande. Cela aussi est trivial à pirater, une fois que vous vous en rendez compte, car il suffit de renifler l'UA rapporté lorsque vous reniflez le cookie de session, et commencez à l'utiliser.

Et maintenant? Adresse IP? Le détournement de session peut se produire derrière un NAT, auquel cas vous êtes foutu. Vos utilisateurs utilisent peut-être l'accès à distance, auquel cas ils sont vissés.

Ce problème n'a pas de solution: il y a aucun moyen. Il ne pourrait pas y avoir de chemin. Si un pirate peut voir vos cookies de session, alors ils peuvent vous déranger, car il n'y a aucune information supplémentaire ou défi lié à quelque chose que seul l'utilisateur connait (mot de passe) qui est envoyé avec chaque demande.

La seule façon de sécuriser la session est de sécuriser la session entière.

0

Est-ce une mesure de sécurité assez fort par lui-même,

Placez deux variables de session pour valider eachother et/ou
Mettre en œuvre la base de données/validation de hachage

Non, et la raison est : Tout ce que votre utilisateur valide peut envoyer à votre serveur pour l'authentification (ID de session, cookies, une chaîne hachée, n'importe quoi!) Peut être reniflé par d'autres si ce n'est pas crypté. Même si le serveur traite les données avec le hachage md5, salt, les vérifications de variable de session double, id ou autre, et stocke ces informations, il est facilement reproduit par le serveur quand il reçoit à nouveau les données usurpées d'une autre source.

Comme beaucoup de gens l'ont suggéré, SSL est le seul moyen d'empêcher ce type d'écoute électronique. Il m'est apparu que, si le serveur devait générer un nouvel identifiant de session pour chaque requête, et permettre au navigateur de ne répondre qu'une seule fois, il ne pourrait théoriquement y avoir qu'une seule requête ou publication d'un pirate avant le serveur et le serveur. navigateur autorisé savait à ce sujet. Encore inacceptable, cependant, car il suffit de faire de sérieux dégâts.

Hey Qu'en est-ce:

Créer un GUID à usage unique et le sel aléatoire et chiffrer avec un mot de passe partagé en utilisant PHP - ceci est envoyé comme l'identifiant de session ou un cookie.

Le client reçoit le cookie, décrypte avec le mot de passe partagé en utilisant javascript (il y a beaucoup de enc/utilitaires dec disponibles)

Définissez le cookie en cours ou l'identifiant de session au GUID.

Cela garantirait que personne ne pourrait pirater la session à moins de connaître le mot de passe, qui n'est jamais envoyé sur le réseau.

SSL semble beaucoup plus facile, et est encore plus sécurisé.

EDIT: Ok, il a été fait - Nevermind ;-)