Home  >  Article  >  Backend Development  >  How to troubleshoot cross-site request forgery errors in PHP?

How to troubleshoot cross-site request forgery errors in PHP?

王林
王林Original
2023-12-17 08:38:311178browse

How to troubleshoot cross-site request forgery errors in PHP?

Cross-site request forgery (CSRF) attack is a common means of network attack, and it is no exception in applications in PHP. It uses the user's login status to carry out attacks, and disguises itself as a legitimate user to submit malicious requests by constructing forged requests, thereby causing harm. This article will introduce how to eliminate CSRF vulnerabilities in PHP applications, including specific code examples and detailed analysis.

  1. Add CSRF token

CSRF attacks bypass the website’s protection mechanism by forging requests. A common bypass method is the “password” attack. To prevent this attack, a CSRF token needs to be added to the website's forms.

Backend code:

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

Frontend code:

<form method="POST" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <!-- 其他表单数据 -->
    <button type="submit">提交</button>
</form>
  1. Use a different CSRF token for each operation

For To further improve security, different CSRF tokens should be used for different operations.

Back-end code:

<?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']);
    //请求数据合法,执行操作
}
?>

Front-end code:

<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. Bind IP address and user agent information

CSRF attack The purpose is to bypass the security verification of the website. The main preventive measure is to add a verification mechanism during the form submission process. To further enhance security, the CSRF token can be bound to the user.

Back-end code:

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

Front-end code:

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

Through the above methods, CSRF vulnerabilities in PHP applications can be effectively eliminated. However, it should be noted that these methods are not absolutely reliable and need to be adjusted and improved based on the actual situation. At the same time, you need to avoid passing CSRF tokens into URLs or cookies to avoid introducing new security risks.

The above is the detailed content of How to troubleshoot cross-site request forgery errors in PHP?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn