Вопрос по php, post – Остановить публикацию данных из другого домена PHP
Я новичок в PHP.
Я пытаюсь остановить публикацию данных с другой веб-страницы.
Проблема, с которой я столкнулся, заключается в том, что кто-то копирует мою форму и вставляет ее на свой веб-сайт. Я хочу, чтобы эти данные в почтовом ящике не могли запускать скрипт.
Как я могу это сделать? Дайте мне знать, если я не достаточно ясен.
Моя контактная форма PHP работает на одной странице с условными утверждениями. то есть, если данные подтвердятся, отправьте.
CSRF - подделка межсайтовых запросов. Сам Джефф есть статья в блоге об этом.
Настоящая XSRF Prevention требует трех частей:
Hidden Input Fields, to prevent someone from just snatching the form and embedding it Timechecking within an epsilon of the form being generated, otherwise someone can generate a valid form once and use the token (depending on impementation/how it's stored) Cookies: this is to prevent a malicious server from pretending it's a client, and performing a man-in-the-middle attack<iframe src="yoursite.com/page.php..
- это ваша страница, где устанавливается cookie. (for realistic solution, I've made an answer below).
<?
$password = "mypass"; //change to something only you know
$hash = md5($password . $_SERVER['REMOTE_ADDR']);
echo "<input type=\"hidden\" name=\"iphash\" value=\"$hash\"/>";
?>
Когда вы проверяете:
$password = "mypass"; //same as above
if ($_POST['iphash'] == md5($password . $_SERVER['REMOTE_ADDR'])) {
//fine
}
else {
//error
}
вы можете проверить заголовок REFERER.
Если вы действительно хотите убедиться, что форма была получена с вашего сайта, вы должны генерировать токен при каждой загрузке формы и присоединять его к сеансу. Простой способ сделать это будет что-то вроде:
$_SESSION['formToken'] = sha1(microtime());
Тогда ваша форма может иметь скрытый ввод:
<input type="hidden" name="token" value='<?=$_SESSION['formToken'];?>' />
и вы можете проверить это при принятии решения, обрабатывать ли данные формы.
Ниже приведен алгоритм предотвращения CSRF:
1) $login_id = user login id (converted to a numeric id using mysql)
2) $a_secret_key = $_SERVER['UNIQUE_ID'];
3) $remote_addr = $_SERVER['REMOTE_ADDR'];
4) Request Date and Time -> A unique reference key -> $refkey
5) $_SESSION['secretkey'] = $_SERVER['UNIQUE_ID'];
Объедините вышеприведенные значения от 1 до 4, чтобы создать файл json при передаче данных на другую страницу.
затем
echo "<input type=\"hidden\" name=\"refkey\" value=\"$refkey\"/>";
На конце получателя:
Страница получателя должна проверить,
1) any json file with $refkey exists at server?
2) If $refkey exists, then check $login_id, $a_secret_key and $remote_addr exists and are correct.
"accepted answer" has security holes, Вместо этого вы должны использовать более безопасные методы. Простой пример:
Step 1: Сначала отключите кадрирование страницы (.php
), где создается форма.php
, В топ добавить:
header('X-Frame-Options: Deny');
Step 2: (important part ! ): Чтобы избежать XSS и сторонних эксплойтов, вы должны создать временный ключ проверки. Например:
ASP.NET
builtin forms use dynamic input crsf (example value: gtlkjh29f9ewduh024cfvefb
)
WordPress
builtin forms use dynamic input nonce (example value: 340297658942346
)
Your settings forms ? Nothing? then it's vulnerable.
Итак, если вы находитесь на пользовательской платформе, которая не имеет встроенных методов проверки временных токенов, то создайте свою, как эта простая концепция:
<?php
$secret_key = 'fjd3vkuw#KURefg'; //change this
$encrypted_value = Cryptor::encrypt( time(), $_SERVER['REMOTE_ADDR'] . $secret_key);
?>
<form>
...
...
<input value="<?php echo $encrypted_value;?>" name="temp_random" type="hidden" />
</form>
(Cryptor code is Вот )
при подаче проверьте:
if(!empty($_POST)){
// ================ STEP 1 (Basic validation) ======== //
// if REFERRER is empty, or it's NOT YOUR HOST, then STOP
if( !isset($_SERVER['HTTP_REFERRER']) || parse_url($_SERVER['HTTP_REFERRER'])['host'] != $_SERVER['HTTP_HOST'] ){
exit("You are not allowed 1 !");
}
// ================ STEP 2 (Stronger validation) ======== //
if ( Cryptor::decrypt( $_POST['temp_random'], $_SERVER['REMOTE_ADDR'] . $secret_key) < time() - 60* 15 ) {
exit("You are not allowed 2 !");
}
...........................................
... Now, you can execute your code here ...
...........................................
}
$ _SERVER ["HTTP_Referrer"] было бы неплохо, но это ненадежно. которое является чем-то MD5, и затем вы проверяете его с другой стороны.