Question

  

Modifier: Depuis, j'ai trouvé et publié une solution efficace et élégante qui permet de transformer des ID tels que 3141592 en chaînes telles que vJST et inversement. Il est disponible pour PHP ici:

     

https://github.com/delight-im/PHP-IDs

     

Fournissant un peu d’arrière-plan, il utilise le hachage multiplicatif de Knuth suivi d’une conversion de base pour générer des identifiants uniques, réversibles et non séquentiels.

Problème:

J'ai des pages dynamiques en PHP où le contenu est affiché en fonction de l'identifiant donné. L'identifiant est toujours soumis via un paramètre GET: page.php? Id = X Cela pose un problème: les visiteurs du site peuvent énumérer les identifiants et parcourir les différentes pages de contenu. Cela ne devrait évidemment pas être possible.

Comment cela pourrait-il être résolu?

Mon approche consiste à coder tous les identifiants dans des liens et des formulaires utilisés ultérieurement en tant que paramètre GET. Au début de chaque page, l'identifiant donné est décodé dans le "réel" id qui est utilisé dans la base de données. Est-ce une bonne approche? Souhaitez-vous choisir un autre moyen?

Solution possible de mon approche:

Je convertirais l'id entier en un entier de base 38 et remplacerais les chiffres par des caractères d'une liste donnée. Je voudrais utiliser ces caractères pour l'ID de chaîne codée:

a-z 0-9 - _

Utiliseriez-vous également d'autres personnages? Pour ces personnages, mon script serait le suivant:

function id2secure($old_number) {
    $alphabet_en = array(0=>'1', 1=>'3', 2=>'5', 3=>'7', 4=>'9', 5=>'0', 6=>'2', 7=>'4', 8=>'6', 9=>'8', 10=>'a', 11=>'c', 12=>'e', 13=>'g', 14=>'i', 15=>'k', 16=>'m', 17=>'o', 18=>'q', 19=>'s', 20=>'u', 21=>'w', 22=>'y', 23=>'b', 24=>'d', 25=>'f', 26=>'h', 27=>'j', 28=>'l', 29=>'n', 30=>'p', 31=>'r', 32=>'t', 33=>'v', 34=>'x', 35=>'z', 36=>'-', 37=>'_');
    $new_number = '';
    while ($old_number > 0) {
        $rest = $old_number%38;
        if (!isset($alphabet_en[$rest])) { return FALSE; }
        $new_number .= $alphabet_en[$rest];
        $old_number = floor($old_number/38);
    }
    $new_number = strrev($new_number);
    return $new_number;
}

Question supplémentaire:

Quelle serait la fonction inverse pour ma fonction?

J'espère que vous pourrez m'aider. Merci!

Était-ce utile?

La solution

Les utilisateurs peuvent-ils accéder aux pages via le site Web? Si la réponse est oui, vous devriez vous demander si cela pose vraiment un problème ou non.

Si ce n'est pas le cas, le problème est que vous ne sécurisez pas vos pages ou, pour le dire autrement, vous vous fiez à l'obscurité pour assurer votre sécurité, ce qui n'est jamais une bonne chose.

Mon conseil? Sécurisez vos pages afin que seuls les bons utilisateurs puissent y accéder ou ne vous inquiétez pas.

Si vous devez vraiment vous en préoccuper, transmettez simplement un champ supplémentaire qui doit être correct pour la page donnée. Je ne construirais pas ceci à partir de l'ID. Peut-être générer un autre numéro ou un GUID lorsque vous créez l'entrée de page dans la base de données. Si les deux champs ne sont pas corrects, n'affichez pas la page.

Oubliez la substitution de caractères simples et d’autres techniques d’obscurcissement naïfs. Ils sont une perte de temps.

Modifier: si vous recherchez des identifiants non séquentiels de même longueur, envisagez d'utiliser des UUID plutôt que des clés primaires à incrémentation automatique. En gros, cela se fait au niveau de l'application:

  • Changez votre clé primaire en char (36);
  • Dans votre instruction insert, vous devez définir la clé et la renseigner avec la fonction MySQL UUID ().

Consultez To UUID ou pas vers l'UUID? et UUID en tant que clé primaire . Cela entraîne une dégradation des performances (en particulier parce que vous utilisez des caractères plutôt que des entiers pour les recherches), mais à moins que vous ne disposiez d'une grande taille (plus d'un million de lignes) ou de données, cela ne posera probablement pas de problème en pratique.

Autres conseils

Utilisez un algorithme de somme de contrôle tel que Luhn :

$id = 1337;

Utilisez un algorithme de somme de contrôle tel que Luhn :

$id = Luhn_Verify(

Utilisez un algorithme de somme de contrôle tel que Luhn :

$id = 1337;

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'] = Luhn_Verify(

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id']; // 1337

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'], 3); if ($id === false) { // someone is trying to guess the ID } else { // $id is valid, do the DB stuff here }

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'] = Luhn_Verify(

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Utilisez un algorithme de somme de contrôle tel que Luhn :

<*>

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>GET['id']; // 1337

EDIT: J'ai oublié de mentionner, mais en utilisant cette méthode, vous pouvez vérifier si un ID est valide sans même avoir à interroger la base de données, exemple:

<*>

Il sera toujours possible de parcourir vos pages de manière séquentielle, bien qu'il soit plus difficile de deviner le motif. Si le motif racine est séquentiel, vous aurez éventuellement un problème (à supposer que ce soit un problème en premier lieu, et pas seulement quelque chose dont vous n’aimez pas l’idée).

Vous pouvez utiliser des nombres aléatoires pour les identifiants. Cela éviterait de deviner facilement les identifiants et l'ordre des pages (encore une fois, si cela compte).

Vous pouvez également utiliser Hashids pour coder / décoder vos identifiants.

  

Ce code a été écrit dans le but de placer les identifiants créés à des endroits visibles, comme l'URL.

  

Hashids est une petite bibliothèque open source qui génère des identifiants courts, uniques et non séquentiels à partir de nombres.
  Il convertit des nombres tels que 347 en chaînes telles que «yr8» ou un tableau de nombres tel que [27, 986] en «3kTMd».
  Vous pouvez également décoder ces identifiants. Ceci est utile pour regrouper plusieurs paramètres en un seul ou simplement pour les utiliser comme UID courts.

Je ne voudrais pas m'inquiéter de ce "problème", mais j'ai quand même utilisé cette méthode sur l'un de mes projets:

Après avoir enregistré une nouvelle page dans la base de données, j'ai généré le md5 de (record_id + page_title) et l'a placé dans le champ spécial code de pagecode . Ensuite, j'ai accédé aux pages par ce code de page au lieu de id. Et mieux vaut indexer le champ pagecode dans la base de données.

  

Les visiteurs du site peuvent énumérer les identifiants.   et simplement marcher à travers tous les   différentes pages de contenu. Ce   ne devrait pas être possible, bien sûr.

Je ne sais pas pourquoi cela devrait poser problème - les utilisateurs peuvent afficher la liste de toutes les pages (publiques, indexées par Googlebot) d'un site Web en tapant simplement site: domain.com dans Google et passez-les en boucle s'ils le souhaitent. Changer l'index unique que vous utilisez ne changera pas cela.

Mais si vous ne voulez vraiment pas que les visiteurs accèdent directement à vos pages, une solution simple consiste à utiliser POST au lieu de GET.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top