#php #security #iframe #hash
#php #Безопасность #iframe #хэш
Вопрос:
В приложении CMS мне иногда нужно открыть iframe другого домена. На данный момент я устанавливаю URL-адрес для этого iframe на что-то очень неясное. Например http://domain.com/iframe/jhghjg34787386 /. Это работает, но теоретически исходный URL-адрес iframe будет сохранен в истории пользователя и может быть доступен из внешнего мира.
Итак, мне интересно использовать основанный на времени подход к постоянно меняющемуся хэшу или строке, которые обрабатываются на стороне запроса и проверяются на стороне источника iframe. Однако я бы хотел, чтобы это было основано на времени.
Я мог бы сделать это, чтобы получить свой хэш:
<?php
$seed = '123456789'; // a password that both the parent and source have
$string = md5(time().$seed);
?>
Но тогда два сервера должны быть точно синхронизированы. Есть ли способ сделать ограничение по времени более нечетким?
Я также открыт для других подходов. Есть ли какой-либо способ проверить, что родительское окно для iframe относится к определенному домену?
Ответ №1:
Вы можете добавить ключ к своему хэшу и отправить временную метку с запросом, например:
$key = "YOUR_SECRET_KEY";
$time = time();
$hash = hash_hmac('sha256', $time, $key);
$url = "https://example.com/iframe?hash=$hashamp;time=$time";
С другой стороны, вы должны сначала проверить, находится ли временная метка в пределах (например, не старше пяти минут), а затем перефразировать ключ и отправленную временную метку. Если вы получаете тот же хэш, запрос действителен.
Примечания:
- не используйте MD5: алгоритм полностью нарушен и больше не обеспечивает никакой безопасности (хотя предполагается, что он все еще работает нормально при использовании с HMAC …)
- вы должны использовать
hash_equals
для сравнения хэшей, чтобы предотвратить временные атаки - мы используем HMAC для обеспечения целостности данных и аутентификации. См. https://crypto.stackexchange.com/questions/1070/why-is-hkx-not-a-secure-mac-construction почему мы не должны просто объединять время и ключ
Комментарии:
1. Пожалуйста, используйте
hash_equals
, посколькуhash_compare
в PHP нет функции.
Ответ №2:
Вы не должны использовать обычный MD5, который; MD5 не предназначен для обеспечения подлинности сообщения. Вместо этого вы можете просто публично указать временную метку вместе с другой информацией (сообщением) в кодировке base64, чтобы она не содержала символ ‘:’. Затем вы можете вычислить код HMAC сообщения, например, с помощью
$hmac = hash_hmac("md5", $message, $secret)
$signed_message = $message . ":" . $hmac
На другом конце вы можете проверить эту подпись, сначала разделив ее на «:», получив $message и $ hmac, затем вы можете проверить подлинность с помощью
$hmac == hash_hmac("md5", $message, $secret)
Если коды совпадают, проверьте, находится ли временная метка в все $message
еще в пределах.
Ответ №3:
Будьте осторожны с использованием MD5 для хеширования — он криптографически нарушен. Существует множество онлайн-сайтов, которые помогают создавать коллизии. Лучше используйте что-то вроде SHA256 и всегда включайте длинную строку для заполнения.
Если пользователю не нужно взаимодействовать с сайтом в iframe, вы можете рассмотреть возможность очистки кода сайта и вставки его непосредственно в свой код. Для этого доступно несколько библиотек.
Как насчет использования чего-то вроде
$hash = hash ( "sha256" , date("h") . 'myverylongsaltstring' );
Пока серверы имеют правильные часовые пояса и синхронизированы с точностью до часа, этот подход будет работать как ваш хэш time() .
Кроме того, вы могли бы использовать что-то вроде TinyURL, чтобы немного запутать ссылку. Что-то вроде http://www.technabled.com/2008/12/create-your-own-tinyurl-with-php-and.html
Ответ №4:
Если он основан на времени, то количество возможных ключей, которые человек должен был бы угадать, было бы крошечным. Поскольку я примерно знаю, когда может быть сгенерирован URL-адрес, и я знаю, как вы его хэшируете, тогда я могу просто создать сотни тысяч ссылок и протестировать их.
Вы должны использовать UUID или что-то эквивалентное. Вероятность столкновения была бы практически невозможна.
Комментарии:
1. Правильно, но я бы также ввел «начальное значение» / пароль, который был бы как у родителя, так и у источника, чтобы хэш нельзя было угадать.
2. Хорошо, прочитав, что такое UUID, да, я бы использовал UUID. Но это не решает проблему. URL-адрес по-прежнему открыт.