Güvenlik kodu için lütfen belirteçlerinizi şu şekilde oluşturmayın: $token = md5(uniqid(rand(), TRUE));
Şunu deneyin:
CSRF Jetonu Oluşturma
PHP 7
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
Not: İşverenimin açık kaynak projelerinden biri, arka porta random_bytes()
ve random_int()
PHP 5 projelerine yönelik bir girişim . MIT lisanslıdır ve Github ve Composer'da paragonie / random_compat olarak mevcuttur .
PHP 5.3+ (veya ext-mcrypt ile)
session_start();
if (empty($_SESSION['token'])) {
if (function_exists('mcrypt_create_iv')) {
$_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
} else {
$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
}
}
$token = $_SESSION['token'];
CSRF Jetonunu Doğrulama
Sadece kullanmayın ==
veya hatta ===
kullanmayın hash_equals()
(yalnızca PHP 5.6+, ancak karma uyumlu kitaplığa sahip önceki sürümlerde mevcuttur ).
if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) {
} else {
}
}
Form Başına Jetonlarla Daha İleri Gitme
Kullanarak jetonları yalnızca belirli bir form için kullanılabilir olacak şekilde daha da kısıtlayabilirsiniz. hash_hmac()
. HMAC, daha zayıf karma işlevlerle (örn. MD5) bile kullanımı güvenli olan özel bir anahtarlı karma işlevdir. Bununla birlikte, bunun yerine SHA-2 ailesinin karma işlevlerini kullanmanızı öneririm.
Önce, bir HMAC anahtarı olarak kullanmak için ikinci bir jeton oluşturun, ardından bunu oluşturmak için aşağıdaki gibi bir mantık kullanın:
<input type="hidden" name="token" value="<?php
echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />
Ve sonra jetonu doğrularken uyumlu bir işlem kullanarak:
$calc = hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
if (hash_equals($calc, $_POST['token'])) {
}
Bir form için üretilen belirteçler, bilinmeden başka bir bağlamda yeniden kullanılamaz $_SESSION['second_token']
. HMAC anahtarı olarak sayfaya az önce bıraktığınızdan farklı bir belirteç kullanmanız önemlidir.
Bonus: Hibrit Yaklaşım + Dal Entegrasyonu
Twig şablonlama motorunu kullanan herkes , Twig ortamına bu filtreyi ekleyerek basitleştirilmiş bir ikili stratejiden yararlanabilir:
$twigEnv->addFunction(
new \Twig_SimpleFunction(
'form_token',
function($lock_to = null) {
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
if (empty($_SESSION['token2'])) {
$_SESSION['token2'] = random_bytes(32);
}
if (empty($lock_to)) {
return $_SESSION['token'];
}
return hash_hmac('sha256', $lock_to, $_SESSION['token2']);
}
)
);
Bu Twig işlevi ile hem genel amaçlı jetonları şu şekilde kullanabilirsiniz:
<input type="hidden" name="token" value="{{ form_token() }}" />
Veya kilitli varyant:
<input type="hidden" name="token" value="{{ form_token('/my_form.php') }}" />
Twig yalnızca şablon oluşturma ile ilgilidir; yine de belirteçleri doğru şekilde doğrulamanız gerekir. Bana göre Twig stratejisi, maksimum güvenlik olasılığını korurken daha fazla esneklik ve basitlik sunuyor.
Tek Kullanımlık CSRF Jetonları
Her CSRF belirtecinin tam olarak bir kez kullanılmasına izin verilmesi gibi bir güvenlik gereksiniminiz varsa, en basit strateji onu her başarılı doğrulamadan sonra yeniden oluşturur. Ancak, bunu yapmak, aynı anda birden çok sekmeye göz atan kişilerle iyi karışmayan her önceki belirteci geçersiz kılar.
Paragon Initiative Enterprises , bu köşe vakalar için bir Anti-CSRF kitaplığı bulunduruyor . Yalnızca tek kullanımlık form başına belirteçlerle çalışır. Oturum verilerinde yeterli sayıda token depolandığında (varsayılan yapılandırma: 65535), ilk olarak en eski kullanılmayan tokenları devre dışı bırakır.
token_time
için kullanılır?