web-dev-qa-db-fra.com

Dois-je masquer les clés primaires (ID) de la base de données dans le frontal de l'application?

Je travaille sur une application qui permet à un modérateur de modifier les informations de l'utilisateur. Donc, pour le moment, j'ai des URL comme

http://www.example.com/user/1/edit
http://www.example.com/user/2/edit

Je suis un peu inquiet ici, car j'expose directement la clé primaire (ID) de la table des utilisateurs de la base de données. Je prends simplement l'ID des URL (par exemple: 1 et 2 des URL ci-dessus), interroge la base de données avec l'ID et obtient les informations utilisateur (bien sûr, je nettoie l'entrée - l'ID de l'URL).

Veuillez noter que je valide chaque demande pour vérifier si le modérateur a accès pour modifier cet utilisateur.

Ce que je fais est-il sûr? Sinon, comment dois-je le faire?

Je peux penser à une alternative, c'est-à-dire avoir une colonne séparée pour la table des utilisateurs avec une clé de 25 caractères et utiliser les clés dans les URL et interroger la base de données avec ces clés.

Cependant,

  • Quelle différence cela fait? (Puisque la clé est exposée maintenant)
  • L'interrogation par rendement de clé primaire résulte plus rapidement que les autres colonnes
53

Le seul élément d'information que vous pourriez espérer "cacher" est le séquence: puisqu'une base de données allouera des valeurs de clé primaire avec un compteur, les personnes qui voient leur clé peuvent faire une supposition quant à quand le compte utilisateur correspondant a été créé. En dehors de cela, il n'y a aucune autre information qu'un plan obscurcissant puisse réellement cacher. L'attaquant sait déjà que des utilisateurs distincts sont référencés via des clés distinctes, et c'est l'étendue de la sémantique de la "clé primaire" de la base de données.

Par conséquent, sauf si vous considérez que l'ordre de création de compte est une information privée qui doit être cachée, je dirais que votre schéma d'obscurcissement est inutile.

37
Thomas Pornin

Un moyen simple serait d'utiliser la méthode utilisée par YouTube et d'autres sites Web. Il s'agit de hashids ( http://hashids.org ).

Avec cette méthode, vous pouvez donner des liens comme: http://www.example.org/user/fce7db/edit tandis que fce7db serait égal à un nombre par exemple: 12

Cela présente l'avantage de performances contrairement à la génération d'un autre hachage aléatoire dans la base de données, car vous ne devez le traduire qu'une seule fois et vous pouvez ensuite rechercher dans la base de données par la clé primaire d'origine comme vous l'avez fait auparavant.

Pour qu'il soit plus difficile pour les utilisateurs de trouver au hasard d'autres identifiants, vous pouvez utiliser un sel secret pour une seule et une longueur minimale pour éviter de les "forcer brutalement".

En ayant un sel secret, les gens peuvent toujours échanger les URL dans des cas comme http://www.example.com/image/c8yDa .

27
Jay Claiton

Non. D'une manière ou d'une autre, vous devez identifier l'enregistrement spécifique avec un identifiant unique dans l'URL. Cela peut être la clé primaire ou autre chose. Si vous devez masquer l'ordre ou la séquence, vous pouvez utiliser une deuxième colonne avec une chaîne aléatoire et unique comme Z2wDKo0ubb1D2VngFh4N.

Si vous souhaitez plus de sécurité, utilisez SSL. Cela n'empêche pas l'utilisateur de voir l'URL et les paramètres, comme l'a noté @eggyal.

En utilisant SSL, les paramètres d'URL sont cryptés et empêchent l'écoute clandestine. Et oui, nous savons maintenant que SSL est défectueux, pas vraiment sécurisé, mais il offre plus de sécurité que de ne pas l'utiliser. Mais n'utilisez pas l'URL pour les mots de passe! Utilisez POST pour vous connecter et soumettre des données, GET pour récupérer des informations, comme toujours.

Voir https://stackoverflow.com/questions/499591/are-https-urls-encrypted

Raisons de ne pas utiliser d'informations secrètes dans une URL: les demandes DNS ne sont probablement pas chiffrées (mais comme le note @tgies dans les commentaires, la partie demande n'est pas incluse, donc pas d'ID ici), l'historique du navigateur et les journaux du serveur.

4
SPRBRN

J'ai créé quelques systèmes qui utilisent ou n'utilisent pas la clé primaire (ou un autre identifiant) dans l'URL. Ce que nous utilisons dépend totalement du facteur de préjudice - par exemple, pour un site qui est uniquement basé sur les données, nous utilisons la clé primaire dans l'URL; nous ne nous soucions pas si quelqu'un parcourt les produits de manière séquentielle.

Pour les systèmes qui ont des exigences de sécurité, au lieu d'utiliser un identifiant séquentiel prévisible, nous avons utilisé l'un des deux schémas:

  1. Nous conservons les informations clés de la session du navigateur. Simple, direct et si notre serveur n'est pas sécurisé, nous avons de plus gros problèmes.
  2. Nous avons généré un nombre aléatoire (et vérifié l'unicité) soit lorsque l'enregistrement est créé OR pour la session uniquement; et utilisé ce nombre aléatoire dans l'URL.

Bonne chance,

Larry

3
LarryN

Oui, vous devez masquer ces identifiants, car vous perdez des informations.

Si votre application est parfaitement sécurisée, la seule information (ab) que les utilisateurs peuvent apprendre est une estimation approximative du nombre d'utilisateurs grâce à l'utilisation de quelque chose appelé Doomsday Argument. De plus, s'ils apprennent les identifiants de plusieurs utilisateurs, ils sauront qui s'est inscrit en premier et pourront deviner à quelle distance cela s'est produit. Et ils peuvent également deviner les identifiants des autres utilisateurs.

Si votre application est parfaitement sécurisée.

Si ce n'est pas le cas, et vous devez toujours supposer que ce n'est pas le cas, vous avez donné des informations utiles. Si un ID utilisateur n'était qu'un nombre aléatoire, un attaquant ne pourrait pas facilement trouver un autre ID valide. Avec les nombres (principalement consécutifs) généralement donnés par une clé primaire automatique, c'est trivial.

Vous pouvez soit modifier la clé primaire, soit ajouter une clé secondaire, si vous souhaitez conserver la facilité d'utilisation des petits nombres à usage interne. Cette nouvelle clé doit généralement être un GUID .

‡: Bien sûr c'est un lien xkcd.

1
SQB

Vous ne fournissez pas suffisamment d'informations sur l'application pour savoir si vous devez la masquer ou non. En tant que tel, cette partie de votre question ne peut pas être répondue. Cependant, si vous devez demander, la réponse est probablement oui, et même si elle ne va pas au-delà de l'appel du devoir, elle offre plus de protection que l'alternative.

Plutôt que de masquer ou d'obscurcir la clé primaire, envisagez de la modifier. Il n'est pas nécessaire que ce soit séquentiel. Lorsque vous créez un nouvel utilisateur, créez un nombre aléatoire de 32 bits, effectuez une sélection rapide pour vous assurer qu'il n'est pas utilisé et utilisez-le comme clé primaire.

Si quelqu'un modifie un utilisateur, il ne pourra pas obtenir d'informations du numéro d'utilisateur, et essayer des numéros immédiatement adjacents au numéro auquel il a actuellement accès est susceptible de produire un enregistrement inexistant.

Les frais généraux/charges de ce système sont minimes. Il nécessite une sélection supplémentaire lors de la création du compte, ce qui est probablement rare, et n'impose pas de mots clés supplémentaires - vous fournissez toujours la clé primaire dans l'URL, donc les recherches dans les bases de données sont toujours rapides, mais la clé n'a aucune information.

0
Adam Davis