8
votes

Développer une stratégie de connexion et d'authentification Secure PHP

Je développe un système de connexion et d'authentification pour un nouveau site PHP et lisez sur les différentes attaques et vulnérabilités. Cependant, c'est un peu déroutant, alors je veux vérifier que mon approche a du sens.

Je prévois de stocker les données suivantes:

  • dans la session: ID utilisateur, haché + salé http_user_agent

  • dans le cookie et dans la base de données: jeton aléatoire, identifiant haché + salé

    sur chaque page, je prévois de procéder à ce qui suit:

    1. Si une session existe, authentifiez à l'aide de celle-ci. Vérifiez que le http_user_agent correspond à celui de la session stockée.

    2. Si aucune session n'existe, utilisez le cookie pour authentifier. Vérifiez que le jeton et l'identifiant dans le cookie correspondent à ceux de la base de données.

    3. Si le cookie est invalide ou n'existe pas, demandez à l'utilisateur de vous connecter.

      Y a-t-il des défauts évidents dans cela? Tant que je fixais un délai d'attente dans le cookie, je devrais être assez sûr, non? Y a-t-il quelque chose qui me manque?

      Merci beaucoup d'avance.


4 commentaires

Considérez également d'utiliser une autre utilisation un système de jeton pour des actions critiques ...


Exactement, le stockage de l'ID de session dans la base de données est une erreur massive. En stockant l'ID de session dans la base de données, vous faites une injection SQL contre votre système beaucoup plus précieux. Vous devez supposer que votre système sera rompu et vous devez avoir un plan d'action traiter avec la violation. C'est pourquoi les mots de passe sont stockés comme des haltes. De plus, plus de PHP est livré avec un gestionnaire de session, si vous réinventez le Néal, je vous assure que ce sera moins sûr.


Il y a beaucoup de bonne lecture ici aussi: Stackoverflow.com/Questions/549/...


Vous devez réutiliser un cadre d'authentification existant chaque fois que possible, car, vraiment complexe. Par exemple, jetez un coup d'œil à github.com/delight-im/php-auth


8 Réponses :


2
votes

Il ne devrait pas y avoir. La session PHP est stockée sur votre serveur pas l'utilisateur. PHP Simpily laisse un cookie de session pointant dessus. Si vous n'êtes pas sur l'hébergement partagé, la session n'a même pas besoin d'être hachée.

joe


0 commentaires

12
votes

Quelques pensées aléatoires:

  1. Et si je volais le cookie de l'un de vos utilisateurs (en utilisant une attaque XSS en injectant un code JS dans votre site Web)? Je tomberai alors au cas échéatif 2. et donc être capable de vous connecter. IMHO, si vous souhaitez une authentification vraiment sécurisée, n'utilisez pas de cookies de type "mémoriser moi" pour stocker les informations d'identification des utilisateurs.
  2. Si vous stockez les informations d'identification dans un cookie, veuillez ne pas stocker le mot de passe en clair.
  3. Vérification du http_user_agent est une bonne première étape pour empêcher le détournement de la session, mais vous pourriez peut-être le combiner avec l'adresse IP? Il est beaucoup plus difficile d'être sur le même hôte que votre cible que de simplement utiliser le même navigateur.

    Mais dans tous les cas, merci d'avoir pris le temps de penser à un bon schéma d'authentification. Beaucoup de développeurs PHP ne le font pas.

    Edit: Pour l'enregistrement, laissez-moi clarifier un point ici: il y a deux cookies dans cette discussion. L'un étant réglé automatiquement par PHP pour propager l'ID de session (parfois, nous voyons des sites Web en le mettant dans l'URL, par exemple www.example.com/page.php?sessionid = [...]), et le second créé par vous Afin de stocker les informations d'identification de l'utilisateur et de l'authentifier lorsque la session est perdue. L'attaque XSS s'applique aux deux, c'est-à-dire qu'un attaquant pourrait voler le cookie de session et détourner la session (qui a une vie limitée) ou voler le cookie de crédits et s'authentifier ultérieurement.


7 commentaires

Vérification d'une combinaison de l'agent utilisateur et les 3 premiers octets de la propriété intellectuelle sont assez bons. J'ai écrit un article sur le sujet à JQueryin.com/2009/11 / 20 / Php-Secure-Sessions .


En effet, l'Agent utilisateur + adresse IP est plus que suffisant. Mais pourquoi déposer le dernier octet? IMO, c'est la partie la plus importante de l'adresse IP, car mon voisin peut être dans le même sous-réseau ISP et avoir ainsi les mêmes trois premiers octets? Great Article BTW, I Personnaly Utilisez deux sels: une fixe dans un fichier de configuration et une génération aléatoire sur la création d'utilisateurs.


Stocker le cookie dans la base de données est une idée horrible. Cela signifie que si un attaquant avait une vulnérabilité d'injection SQL, il pourrait immédiatement avoir accès sans avoir à craquer un mot de passe haché.


Au point 2., en stockant le cookie, je ne voulais pas dire dans la base de données, mais je voulais dire stocker les informations d'identification dans un cookie. Je vais éditer ma réponse pour faire clairement les choses.


L'agent utilisateur peut être utilisé. Vous n'avez aucune idée de ce dont vous parlez. Vous n'avez jamais détourné une session, même si c'était juste votre système local. Ne répandez pas de mensonges!


Où ai-je dit qu'un agent d'utilisateur ne peut pas être spoofé? Au lieu d'insulter les autres, postez des commentaires qui sont fondamentalement inutiles et de promouvoir un projet aléatoire (que je soupçonne que vous avez peut-être écrit), pourquoi ne vous liez pas à quelque chose comme owasp.org qui aurait été beaucoup plus utile pour l'OP?


BTW, si un attaquant peut effectuer une injection SQL et récupérer quelque chose de la DB (votre argument sur la conservation des cookies de votre réponse), les cookies sont les moins de ses préoccupations (et de vos problèmes) ...



1
votes

dépend de la sécurité que vous voulez être ..

Vulnérabilités croisées: Disons dire qu'un autre site dirige le navigateur de soumettre un formulaire à votre site qui fait quelque chose comme l'affichage du spam (ou de pire) si cet utilisateur est déjà connecté sur la soumission de formulaire fonctionnera. Vous aurez besoin de vérifier le référent et un formidable caché généré pour chaque formulaire pour protéger contre cette entièrement.

Deuxièmement: Si vous avez un trafic élevé à moyen, les sessionsID peuvent être répétés ou même devinés, je vérifierais une pièce d'identité générée par une seconde main stockée dans les cookies des utilisateurs.


0 commentaires

1
votes

Le schéma semble inutilement complexe de quelques égards, en ce que la complexité supplémentaire ne vous gagne pas de fonctionnalité ou de sécurité.

  1. Toutes les données envoyées par le navigateur (par exemple les cookies, l'agent utilisateur) sont spoofables. Vérification de l'utilisateur-Agent n'entraînera que lorsque l'attaquant est derrière le même NAT que l'utilisateur usurculé et l'attaquant utilise un navigateur différent, mais ne pense pas changer l'agent utilisateur.
  2. Sessions Stockez le côté du client de la session ID avec des cookies ou un paramètre de requête URL. Si vous souhaitez prolonger la durée de vie d'une session, utilisez session_set_cookie_params pour garder le cookie de session autour plus longtemps.

    L'agent utilisateur n'est pas des données secrètes, alors hachage, il est inutile.

    Les attaques que la session Cookie + Vérification de la télécommande ne va pas attraper sont:

    1. L'attaquant est derrière le même NAT que l'utilisateur
    2. Attaques d'injection aveugle, où l'attaquant intervient l'adresse IP de l'utilisateur. Malgré sa rédaction, celles-ci peuvent toujours faire des dégâts.
    3. Attaques qui utilisent le navigateur propre de l'utilisateur, telle que Demande inter-sites Falory (CSRF).

      2) pourrait être empêché si vous pouvez déterminer un moyen d'envoyer un défi au navigateur de l'utilisateur, qui doit être répondu avant de remplir la demande, mais cela est délicat lorsque vous n'avez pas écrit le client. Avec Ajax, cela peut être fait. 3) (comme indiqué par MindStalker) peut être empêché en vérifiant l'en-tête de référateur, qui fonctionne car les attaques CSRF n'ont pas la capacité d'affecter les en-têtes arbitraires et que XMLHTTPRequest ne devrait pas permettre à l'en-tête du référateur (selon les < Un href = "http://www.w3.org/tr/xmlhttprecest/#the-sequestheader-method" rel = "Nofollow Noreferrer"> W3C Standard , bien que les implémentations puissent ne pas être conformes). Avec des iframes, il pourrait être possible de contourner un chèque de référateur. En outre, l'en-tête de référateur peut être bloqué côté client.


0 commentaires

2
votes

stocker le cookie dans la base de données est une idée horriblebe. Cela signifie que si un attaquant avait une vulnérabilité d'injection SQL, il pourrait immédiatement avoir accès sans avoir à craquer un mot de passe haché.

Parler de laquelle vous devez utiliser SHA256 pour les mots de passe, si vous utilisez MD5 (), vous êtes techniquement vulnérable à l'attaque et que vous pourriez recevoir un numéro de CVE.

Ne générez jamais votre propre identifiant de session, utilisez Session_Start () et le $ _session Super Global.

Ceci est un moyen sûr de rediriger les gens. Si vous ne meurez pas après l'en-tête (), le reste du code PHP est toujours exécuté, même si ce n'est pas affiché par des navigateurs normaux (les pirates les voient toujours :) xxx

à Soyez honnête si la sécurité vous confond, n'écrivez pas aux systèmes de sécurité. Les gens ont écrit plus de 1 000 systèmes de connexion pour PHP uniquement et la majorité sont vulnérables. Ce projet dispose d'un système d'authentification sécurisé: http://code.google.com/p/michael-the- messager / téléchargements / liste


3 commentaires

Sur votre premier point - je ne veux pas dire que cela prendra le cookie de l'utilisateur et le stockera dans la base de données; ce serait idiot! Je veux dire qu'un jeton et un identifiant sont créés, puis une copie est placée dans le cookie et l'autre dans la base de données. Aucune donnée de la cookie passe dans la base de données, il ne peut donc pas être injecté de cette façon. Merci pour la chose à propos de l'en-tête (), je ne savais jamais ça.


Exactement, c'est une erreur massive. En stockant la valeur de la cookie dans la base de données, vous faites une injection SQL contre votre système beaucoup plus précieux. Vous devez supposer que votre système sera rompu et vous devez avoir un plan d'action traiter avec la violation. C'est pourquoi les mots de passe sont stockés comme des haltes. De plus, plus de PHP est livré avec un gestionnaire de session, si vous réinventez le Néal, je vous assure que ce sera moins sûr.


Ne vous inquiétez pas - je n'ai aucune intention de créer mon propre gestionnaire de session!



1
votes

La plupart des sites utilisent simplement la session PHP; Les données de session ($ _session) sont dans a Fichier sur votre serveur . Tout ce qui est envoyé au navigateur est un identifiant de session. Assurez-vous de régénérer la session chaque demande ( session_regenerèrent_id ). Vous n'avez pas besoin d'envoyer deux cookies ou quoi que ce soit.

Ceci est moins vulnérable au détournement de la session car chaque demande est une nouvelle pièce d'identité, une ancienne ancienne interceptée par un attaquant est inutile.

La meilleure solution, évidemment, serait d'utiliser SSL tout au long de la session.


0 commentaires

0
votes

IMHO Il est également important que les informations de session sont modifiées après une connexion de succès. Pour enregistrer les informations de session dans une base de données ne sauvegarder pas à cause des injections.


0 commentaires

0
votes

-Utilisez SHA1 avec du sel -Out Cours, vous devez définir que chaque formulaire n'est pas un jeton aussi utilisé pour chaque formulaire. Que vous créez chaque entrée de formulaire et assainissez-le à l'aide de Preg_Match. Un processus appelé assainissement.


0 commentaires