Скрыть идентификаторы автоинкремента в параметре GET (PHP) - PullRequest
0 голосов
/ 15 сентября 2009

Редактировать: С тех пор я нашел и опубликовал эффективное и элегантное решение, которое преобразует идентификаторы, такие как 3141592, в строки, такие как vJST и обратно. Это доступно для PHP здесь:

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

Предоставляя некоторый фон, он использует мультипликативное хеширование Кнута с последующим базовым преобразованием для генерации уникальных, обратимых непоследовательных идентификаторов.

Проблема:

У меня есть динамические страницы в PHP, где содержимое отображается в соответствии с заданным идентификатором. Идентификатор всегда передается через параметр GET: page.php? Id = X Это вызывает проблему: посетители сайта могут перечислять идентификаторы и просто просматривать все страницы с различным контентом. Конечно, это не должно быть возможным.

Как это можно решить?

Мой подход заключается в кодировании всех идентификаторов в ссылках и формах, которые позже используются в качестве параметра GET. В начале каждой страницы данный идентификатор декодируется в «реальный» идентификатор, который используется в базе данных. Это хороший подход? Вы бы выбрали другой путь?

Возможное решение моего подхода:

Я бы преобразовал целочисленный идентификатор в целое число 38 и заменил цифры на символы из данного списка. Я бы использовал эти символы для идентификатора кодированной строки:

a-z 0-9 - _

Не могли бы вы использовать и других персонажей? Для этих персонажей мой сценарий будет таким:

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;
}

Дополнительный вопрос:

Какая была бы обратная функция для моей функции?

Надеюсь, вы мне поможете. Спасибо!

Ответы [ 6 ]

8 голосов
/ 15 сентября 2009

Могут ли пользователи попасть на страницы через веб-сайт? Если ответ «да», вы должны спросить себя, действительно ли это проблема или нет.

Если нет, то проблема заключается в том, что вы не защищаете свои страницы или, если выразиться иначе: вы полагаетесь на неясность в плане безопасности, которая никогда не будет хорошим ходом.

Мой совет? Либо защитите свои страницы, чтобы к ним могли обращаться только нужные пользователи, либо не беспокойтесь об этом.

Если вам действительно нужно беспокоиться об этом, просто передайте дополнительное поле, которое должно быть правильным для данной страницы. Я бы не стал строить это из ID. Возможно, сгенерируйте другой номер или GUID при создании записи страницы в базе данных. Если оба поля неправильные, не отображайте страницу.

Забудьте о простой замене символов и других наивных методах запутывания. Они пустая трата вашего времени.

Редактировать: если вы используете непоследовательные идентификаторы одинаковой длины, рассмотрите возможность использования UUID вместо первичных ключей с автоматическим приращением. В основном это делается на уровне приложения:

  • Измените свой первичный ключ на char (36);
  • В вашем операторе вставки вы должны установить ключ и заполнить его функцией MySQL UUID ().

Взгляните на На UUID или нет на UUID? и UUID в качестве первичного ключа . Это приводит к снижению производительности (в частности, потому что вы используете символы, а не целые числа для поиска), но если у вас большой (более 1 миллиона строк) или данных, это, вероятно, не будет проблемой на практике.

1 голос
/ 15 сентября 2009

Используйте алгоритм контрольной суммы, такой как Luhn :

$id = 1337;

$_GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits
$_GET['id'] = Luhn_Verify($_GET['id'], 3); // 1337, returns the original number of false if validation fails

echo $_GET['id']; // 1337

РЕДАКТИРОВАТЬ: я забыл упомянуть, но с помощью этого метода вы можете проверить, является ли идентификатор действительным, даже не запрашивая базу данных, например:

$id = Luhn_Verify($_GET['id'], 3);

if ($id === false)
{
    // someone is trying to guess the ID
}

else
{
    // $id is valid, do the DB stuff here
}
0 голосов
/ 27 сентября 2016

Вы также можете использовать Хашиды для кодирования / декодирования ваших идентификаторов.

Этот код был написан с целью размещения созданных идентификаторов в видимых местах - например, в URL.

Hashids - это небольшая библиотека с открытым исходным кодом, которая генерирует короткие уникальные непоследовательные идентификаторы из чисел.
Он преобразует числа типа 347 в строки типа «yr8» или массив чисел типа [27, 986] в «3kTMd».
Вы также можете декодировать эти идентификаторы обратно. Это полезно при объединении нескольких параметров в один или при простом использовании их в качестве коротких UID.

0 голосов
/ 15 сентября 2009

Я бы не стал беспокоиться об этой «проблеме», но в любом случае я использовал в одном из своих проектов такой метод:

После сохранения новой страницы в БД я сгенерировал md5 of (record_id + page_title) и поместил ее в специальное поле pagecode. Затем я получил доступ к страницам по этому коду страницы вместо идентификатора. И лучше индексировать поле pagecode в базе данных.

0 голосов
/ 15 сентября 2009

Посетители сайта могут перечислять идентификаторы и просто пройти через все страницы с различным содержанием. это конечно, это невозможно.

Я не уверен, почему это должно быть проблемой - люди могут просматривать список всех (общедоступных, проиндексированных с помощью Googlebot) страниц на веб-сайте, просто набрав site:domain.com в Google, и просматривать их, если они пожелают , Изменение используемого вами уникального индекса не изменит этого.

Но если вы действительно не хотите, чтобы посетители обращались к вашим страницам напрямую, простое быстрое решение состоит в использовании POST вместо GET.

0 голосов
/ 15 сентября 2009

По-прежнему будет возможно последовательно просматривать ваши страницы, хотя будет сложнее угадать шаблон. Пока корневой шаблон является последовательным, у вас со временем возникнет проблема (если предположить, что это на самом деле проблема в первую очередь, а не просто то, что вам не нравится по идее).

Вы можете использовать случайные числа для идентификаторов. Это помешает легко угадать идентификаторы страниц и порядок страниц (опять же, если это имеет значение).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...