PHP를 사용하여 사이트 간 요청 위조(CSRF) 토큰을 올바르게 추가하는 방법
웹 사이트의 양식에 보안을 추가하려고 합니다.폼 중 하나는 AJAX를 사용하고 다른 하나는 간단한 "문의" 폼입니다.CSRF 토큰을 추가하려고 합니다.문제는 토큰이 HTML "value"에만 표시되는 것입니다.나머지 시간에는 값이 비어 있습니다.AJAX 폼에서 사용하고 있는 코드는 다음과 같습니다.
PHP:
if (!isset($_SESSION)) {
session_start();
$_SESSION['formStarted'] = true;
}
if (!isset($_SESSION['token'])) {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
HTML:
<input type="hidden" name="token" value="<?php echo $token; ?>" />
좋은 의견이라도 있나?
보안 코드의 경우, 다음과 같은 방법으로 토큰을 생성하지 마십시오.$token = md5(uniqid(rand(), TRUE));
rand()
예측 가능한uniqid()
최대 29비트의 엔트로피만 더하면md5()
엔트로피를 더하는 것이 아니라 결정적으로 섞을 뿐이다.
이것을 시험해 보세요.
CSRF 토큰 생성
PHP 7
session_start();
if (empty($_SESSION['token'])) {
$_SESSION['token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token'];
사이드노트:제 고용주의 오픈 소스 프로젝트 중 하나는 백포트 이니셔티브입니다.random_bytes()
그리고.random_int()
PHP 5 프로젝트로 이동합니다.MIT 라이선스로 Github 및 Composer에서 paragonie/random_compat으로 사용할 수 있습니다.
PHP 5.3+(또는 ext-mcrypt 포함)
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 토큰 확인
사용만 하지 마세요.==
또는 심지어===
, 를 사용합니다(PHP 5.6+ 만, 해시 호환 라이브러리의 이전 버전에서 사용 가능).
if (!empty($_POST['token'])) {
if (hash_equals($_SESSION['token'], $_POST['token'])) {
// Proceed to process the form data
} else {
// Log this as a warning and keep an eye on these attempts
}
}
폼별 토큰을 사용한 추가 기능
를 사용하여 토큰을 특정 형식에서만 사용할 수 있도록 제한할 수 있습니다. HMAC는 더 약한 해시 함수(예: MD5)에서도 안전하게 사용할 수 있는 특정 키 해시 함수입니다.단, 해시함수의 SHA-2 패밀리를 사용하는 것이 좋습니다.
먼저 HMAC 키로 사용할 두 번째 토큰을 생성한 후 다음과 같은 논리를 사용하여 렌더링합니다.
<input type="hidden" name="token" value="<?php
echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />
다음으로 토큰을 확인할 때 동일한 연산을 사용합니다.
$calc = hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
if (hash_equals($calc, $_POST['token'])) {
// Continue...
}
한 양식에 대해 생성된 토큰은 모르는 한 다른 컨텍스트에서 재사용할 수 없습니다.$_SESSION['second_token']
. 페이지에 드롭한 토큰이 아닌 별도의 토큰을 HMAC 키로 사용하는 것이 중요합니다.
보너스: 하이브리드 어프로치 + Twig 통합
Twig 템플릿 엔진을 사용하는 모든 사용자는 Twig 환경에 이 필터를 추가하여 단순화된 이중 전략을 활용할 수 있습니다.
$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']);
}
)
);
이 Twig 기능을 사용하면 다음과 같은 범용 토큰을 모두 사용할 수 있습니다.
<input type="hidden" name="token" value="{{ form_token() }}" />
또는 잠금된 변형:
<input type="hidden" name="token" value="{{ form_token('/my_form.php') }}" />
Twig는 템플릿 렌더링에만 관심이 있으므로 토큰을 올바르게 검증해야 합니다.Twig 전략은 최대의 보안 가능성을 유지하면서 뛰어난 유연성과 단순성을 제공합니다.
일회용 CSRF 토큰
각 CSRF 토큰을 1회만 사용할 수 있는 보안 요건이 있는 경우 검증이 성공할 때마다 가장 간단한 전략에 의해 토큰이 재생성됩니다.그러나 이렇게 하면 한 번에 여러 탭을 탐색하는 사용자와 잘 섞이지 않는 모든 이전 토큰이 무효화됩니다.
Paragon Initiative Enterprises는 이러한 코너 케이스에 대해 Anti-CSRF 라이브러리를 관리하고 있습니다.1회용 폼 토큰에서만 사용할 수 있습니다.세션 데이터에 충분한 토큰이 저장되면(기본 설정: 65535), 가장 오래된 회수되지 않은 토큰이 먼저 사이클아웃됩니다.
보안 경고:
md5(uniqid(rand(), TRUE))
랜덤 번호를 생성하는 안전한 방법이 아닙니다.암호학적으로 안전한 난수 생성기를 활용하는 솔루션 및 자세한 내용은 이 답변을 참조하십시오.
네 IF에 다른 게 필요하겠구나
if (!isset($_SESSION['token'])) {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
}
else
{
$token = $_SESSION['token'];
}
''$token
때 .
md5()와 함께 time() 메서드를 사용하여 고유하게 만들 수 있습니다.
if (!isset($_SESSION['token']))
{
$time = time();
$_SESSION['token'] = md5($time);
$_SESSION['token_time'] = $time;
}
else
{
$token = $_SESSION['token'];
}
언급URL : https://stackoverflow.com/questions/6287903/how-to-properly-add-cross-site-request-forgery-csrf-token-using-php
'programing' 카테고리의 다른 글
phpMailer 및 PHP를 사용하여 양식에서 첨부 파일 보내기 (0) | 2022.10.09 |
---|---|
그렇지 않으면 PHP 문에서 AND/OR 사용 (0) | 2022.10.09 |
panda DataFrame 열에 있는 NaN 값은 어떻게 계산합니까? (0) | 2022.10.08 |
Hover를 사용한 부트스트랩 드롭다운 (0) | 2022.10.08 |
WordPress에서 사용하는 해시 유형은 무엇입니까? (0) | 2022.10.08 |