首頁  >  文章  >  後端開發  >  如何排除PHP中的跨站請求偽造錯誤?

如何排除PHP中的跨站請求偽造錯誤?

王林
王林原創
2023-12-17 08:38:311186瀏覽

如何排除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或Cookie中,以免帶來新的安全隱患。

以上是如何排除PHP中的跨站請求偽造錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn