>  기사  >  백엔드 개발  >  PHP에서 사이트 간 요청 위조 오류를 해결하는 방법은 무엇입니까?

PHP에서 사이트 간 요청 위조 오류를 해결하는 방법은 무엇입니까?

王林
王林원래의
2023-12-17 08:38:311173검색

PHP에서 사이트 간 요청 위조 오류를 해결하는 방법은 무엇입니까?

교차 사이트 요청 위조(CSRF) 공격은 네트워크 공격의 일반적인 수단이며 PHP 애플리케이션에서도 예외는 아닙니다. 사용자의 로그인 상태를 이용하여 공격을 수행하고, 합법적인 사용자로 위장하여 위조된 요청을 구성하여 악의적인 요청을 제출함으로써 피해를 입힙니다. 이 기사에서는 특정 코드 예제 및 자세한 분석을 포함하여 PHP 애플리케이션에서 CSRF 취약점을 제거하는 방법을 소개합니다.

  1. CSRF 토큰 추가

CSRF 공격은 요청을 위조하여 웹사이트의 보호 메커니즘을 우회합니다. 일반적인 우회 방법은 "비밀번호" 공격입니다. 이 공격을 방지하려면 CSRF 토큰을 웹사이트 양식에 추가해야 합니다.

백엔드 코드:

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    session_start();
    if($_POST['csrf_token'] == $_SESSION['csrf_token']){
        //请求数据合法,执行操作
    }else{
        //CSRF令牌不合法
    }
}
?>

프런트엔드 코드:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <!-- 其他表单数据 -->
    <button type="submit">提交</button>
</form>
  1. 작업마다 다른 CSRF 토큰을 사용하세요.

보안을 더욱 강화하려면 작업마다 다른 CSRF 토큰을 사용해야 합니다.

백엔드 코드:

<?php
//生成新的CSRF令牌
function generate_csrf_token(){
    return md5(mt_rand(1, 1000000) . microtime());
}
//验证CSRF令牌
function validate_csrf_token($token){
    if(!isset($_SESSION['csrf_token']) || $_SESSION['csrf_token'] !== $token){
        die("CSRF Token验证失败");
    }
}
//生成CSRF令牌
if(!isset($_SESSION['csrf_token'])){
    //不存在令牌,生成新的令牌
    $_SESSION['csrf_token'] = generate_csrf_token();
}
//用户提交的数据需要先进行CSRF令牌验证
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    validate_csrf_token($_POST['csrf_token']);
    //请求数据合法,执行操作
}
?>

프런트엔드 코드:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo generate_csrf_token(); ?>">
    <input type="hidden" name="action" value="delete">
    <input type="hidden" name="id" value="123">
    <button type="submit">删除用户</button>
</form>
  1. IP 주소와 사용자 에이전트 정보 바인딩

CSRF 공격의 목적은 웹사이트의 보안 검증을 우회하는 것이며, 예방 조치는 주로 양식 제출 과정에서 확인 메커니즘이 추가되었습니다. 보안을 더욱 강화하기 위해 CSRF 토큰을 사용자에게 바인딩할 수 있습니다.

백엔드 코드:

<?php
//生成新的CSRF令牌
function generate_csrf_token(){
    return md5(mt_rand(1, 1000000) . microtime());
}
//验证CSRF令牌
function validate_csrf_token($token){
    if(!isset($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])
        || !in_array($_SERVER['HTTP_USER_AGENT'], $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])){
        die("CSRF Token验证失败");
    }
    if(!isset($_SESSION['csrf_tokens'][$token])){
        die("CSRF Token验证失败");
    }else{
        unset($_SESSION['csrf_tokens'][$token]);
    }
}
//生成CSRF令牌
if(!isset($_SESSION['csrf_tokens'])){
    $_SESSION['csrf_tokens'] = [];
}
if(!isset($_SESSION['csrf_ips'])){
    $_SESSION['csrf_ips'] = [];
}
if(!isset($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']])){
    $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']] = [$_SERVER['HTTP_USER_AGENT']];
}else{
    $_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']][] = $_SERVER['HTTP_USER_AGENT'];
    //限制用户代理
    if(count($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']]) > 3){
        array_shift($_SESSION['csrf_ips'][$_SERVER['REMOTE_ADDR']]);
    }
}
$new_token = generate_csrf_token();
$_SESSION['csrf_tokens'][$new_token] = true;
?>

프런트엔드 코드:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $new_token; ?>">
    <input type="hidden" name="action" value="delete">
    <input type="hidden" name="id" value="123">
    <button type="submit">删除用户</button>
</form>

위의 방법을 통해 PHP 애플리케이션의 CSRF 취약점을 효과적으로 제거할 수 있습니다. 그러나 이러한 방법은 절대적으로 신뢰할 수 있는 것은 아니며 실제 상황에 따라 조정 및 개선이 필요하다는 점에 유의해야 합니다. 동시에 새로운 보안 위험이 발생하지 않도록 CSRF 토큰을 URL이나 쿠키로 전달하지 않아야 합니다.

위 내용은 PHP에서 사이트 간 요청 위조 오류를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.