programing

PHP를 사용하여 사이트 간 요청 위조(CSRF) 토큰을 올바르게 추가하는 방법

kingscode 2022. 10. 8. 17:25
반응형

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

이것을 시험해 보세요.

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

반응형