Rumah pembangunan bahagian belakang tutorial php Yii2框架的csrf验证原理分析及token缓存解决方案

Yii2框架的csrf验证原理分析及token缓存解决方案

Apr 25, 2019 pm 03:20 PM
rangka kerja yii

本文主要分三个部分,首先简单介绍csrf,接着对照源码重点分析一下yii框架的验证原理,最后针对页面缓存导致的token被缓存提出一种可行的方案。涉及的知识点会作为附录附于文末。感兴趣的朋友了解一下吧。

1.CSRF描述

CSRF全称为“Cross-Site Request Forgery”,是在用户合法的SESSION内发起的攻击。黑客通过在网页中嵌入Web恶意请求代码,并诱使受害者访问该页面,当页面被访问后,请求在受害者不知情的情况下以受害者的合法身份发起,并执行黑客所期待的动作。以下HTML代码提供了一个“删除产品”的功能:

<a href="http://www.shop.com/delProducts.php?id=100" "javascript:return confirm(&#39;Are you sure?&#39;)">Delete</a>
Salin selepas log masuk

假设程序员在后台没有对该“删除产品”请求做相应的合法性验证,只要用户访问了该链接,相应的产品即被删除,那么黑客可通过欺骗受害者访问带有以下恶意代码的网页,即可在受害者不知情的情况下删除相应的产品。

2.yii的csrf验证原理 /vendor/yiisoft/yii2/web/Request.php简写为Request.php

/vendor/yiisoft/yii2/web/Controller.php简写为Controller.php

开启csrf验证

在控制器里将enableCsrfValidation为true,则控制器内所有操作都会开启验证,通常做法是将enableCsrfValidation为false,而将一些敏感操作设为true,开启局部验证。

public $enableCsrfValidation = false;
/**
 * @param \yii\base\Action $action
 * @return bool
 * @desc: 局部开启csrf验证(重要的表单提交必须加入验证,加入$accessActions即可
 */
public function beforeAction($action){
    $currentAction = $action->id;
    $accessActions = [&#39;vote&#39;,&#39;like&#39;,&#39;delete&#39;,&#39;download&#39;];
    if(in_array($currentAction,$accessActions)) {
        $action->controller->enableCsrfValidation = true;
    }
    parent::beforeAction($action);
    return true;
}
Salin selepas log masuk

生成token字段

在Request.php

首先通过安全组件Security获取一个32位的随机字符串,并存入cookie或session,这是原生的token.

/**
 * Generates  an unmasked random token used to perform CSRF validation.
 * @return string the random token for CSRF validation.
 */
protected function generateCsrfToken()
{
    $token = Yii::$app->getSecurity()->generateRandomString();
    if ($this->enableCsrfCookie) {
        $cookie = $this->createCsrfCookie($token);
        Yii::$app->getResponse()->getCookies()->add($cookie);
    } else {
        Yii::$app->getSession()->set($this->csrfParam, $token);
    }
    return $token;
}
Salin selepas log masuk

接着通过一系列加密替换操作,生成加密后_csrfToken,这个是传给浏览器的token. 先随机产生CSRF_MASK_LENGTH(Yii2里默认是8位)长度的字符串 mask

对mask和token进行如下运算 str_replace(&#39;+&#39;, &#39;.&#39;, base64_encode($mask . $this->xorTokens($token, $mask))); $this->xorTokens($arg1,$arg2) 是一个先补位异或运算

/**
 * Returns the XOR result of two strings.
 * If the two strings are of different lengths, the shorter one will be padded to the length of the longer one.
 * @param string $token1
 * @param string $token2
 * @return string the XOR result
 */
private function xorTokens($token1, $token2)
{
    $n1 = StringHelper::byteLength($token1);
    $n2 = StringHelper::byteLength($token2);
    if ($n1 > $n2) {
        $token2 = str_pad($token2, $n1, $token2);
    } elseif ($n1 < $n2) {
        $token1 = str_pad($token1, $n2, $n1 === 0 ? &#39; &#39; : $token1);
    }
    return $token1 ^ $token2;
}
public function getCsrfToken($regenerate = false)
{
    if ($this->_csrfToken === null || $regenerate) {
        if ($regenerate || ($token = $this->loadCsrfToken()) === null) {
            $token = $this->generateCsrfToken();
        }
        // the mask doesn&#39;t need to be very random
        $chars = &#39;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.&#39;;
        $mask = substr(str_shuffle(str_repeat($chars, 5)), 0, static::CSRF_MASK_LENGTH);
        // The + sign may be decoded as blank space later, which will fail the validation
        $this->_csrfToken = str_replace(&#39;+&#39;, &#39;.&#39;, base64_encode($mask . $this->xorTokens($token, $mask)));
    }

    return $this->_csrfToken;
}
Salin selepas log masuk

验证token

在controller.php里调用request.php里的validateCsrfToken方法

/**
 * @inheritdoc
 */
public function beforeAction($action)
{
    if (parent::beforeAction($action)) {
        if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
            throw new BadRequestHttpException(Yii::t(&#39;yii&#39;, &#39;Unable to verify your data submission.&#39;));
        }
        return true;
    }
    
    return false;
}
public function validateCsrfToken($token = null)
{
    $method = $this->getMethod();
    if (!$this->enableCsrfValidation || in_array($method, [&#39;GET&#39;, &#39;HEAD&#39;, &#39;OPTIONS&#39;], true)) {
        return true;
    }

    $trueToken = $this->loadCsrfToken();//如果开启了enableCsrfCookie,CsrfToken就从cookie里取,否者从session里取(更安全)

    if ($token !== null) {
        return $this->validateCsrfTokenInternal($token, $trueToken);
    } else {
        return $this->validateCsrfTokenInternal($this->getBodyParam($this->csrfParam), $trueToken)
            || $this->validateCsrfTokenInternal($this->getCsrfTokenFromHeader(), $trueToken);
    }
}
Salin selepas log masuk

获取客户端传入

$this->getBodyParam($this->csrfParam)
Salin selepas log masuk

然后是validateCsrfTokenInternal

private function validateCsrfTokenInternal($token, $trueToken)
{
    if (!is_string($token)) {
        return false;
    }
    $token = base64_decode(str_replace(&#39;.&#39;, &#39;+&#39;, $token));
    $n = StringHelper::byteLength($token);
    if ($n <= static::CSRF_MASK_LENGTH) {
        return false;
    }
    $mask = StringHelper::byteSubstr($token, 0, static::CSRF_MASK_LENGTH);
    $token = StringHelper::byteSubstr($token, static::CSRF_MASK_LENGTH, $n - static::CSRF_MASK_LENGTH);
    $token = $this->xorTokens($mask, $token);

    return $token === $trueToken;
}
Salin selepas log masuk

加密时用的是 str_replace(&#39;+&#39;, &#39;.&#39;, base64_encode(mask.mask.this->xorTokens(token,token,mask))); 解密 1.首先要把.替换成+ 2.然后base64_decode 再 根据长度分别取出mask和mask和this->xorTokens(token,token,mask) ; 为了说明方便 this−>xorTokens(this−>xorTokens(token, $mask) 这里称作 token1 然后 进行mask和token1的异或运算,即得token 注意在加密时

token1=token^mask
Salin selepas log masuk

所以 解密时

token=mask^token1=mask^(token^mask)
Salin selepas log masuk

3.token缓存的解决方案

当页面整体被缓存后,token也被缓存导致验证失败,一种常见的解决思路是每次提交前重新获取token,这样就可以通过验证了。

附录:

str_pad(),该函数返回 input 被从左端、右端或者同时两端被填充到制定长度后的结果。如果可选的 pad_string 参数没有被指定,input 将被空格字符填充,否则它将被 pad_string 填充到指定长度;

str_shuffle() 函数打乱一个字符串,使用任何一种可能的排序方案。

因为yii2 csrf的验证的加解密 涉及到异或运算

所以需要先补充php里字符串异或运算的相关知识,不需要的可以跳过

^异或运算 不一样返回1 否者返回 0 在PHP语言中,经常用来做加密的运算,解密也直接用^就行 字符串运算时 利用字符的ascii码转换为2进制来运算 单个字符运算

1.对于单个字符和单个字符的 直接计算其结果即可 比如表里的a^b

2.对于长度一样的多个字符串 如表里的ab^cd 计算a^c对应的结果和和b^d对应的结果 对应的字符连接起来

相关教程:PHP视频教程

Atas ialah kandungan terperinci Yii2框架的csrf验证原理分析及token缓存解决方案. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Pembangunan API RESTful dalam rangka kerja Yii Pembangunan API RESTful dalam rangka kerja Yii Jun 21, 2023 pm 12:34 PM

Yii ialah rangka kerja MVC berprestasi tinggi berdasarkan PHP Ia menyediakan set alat dan fungsi yang sangat kaya untuk menyokong pembangunan aplikasi web yang pantas dan cekap. Antaranya, fungsi RESTfulAPI bagi rangka kerja Yii telah menarik lebih banyak perhatian dan kasih sayang pembangun, kerana menggunakan rangka kerja Yii boleh membina antara muka RESTful berprestasi tinggi dan mudah berskala, memberikan sokongan kuat untuk pembangunan aplikasi web. Pengenalan kepada RESTfulAPI RESTfulAPI ialah a

Cara menggunakan rangka kerja Yii dalam PHP Cara menggunakan rangka kerja Yii dalam PHP Jun 27, 2023 pm 07:00 PM

Dengan perkembangan pesat aplikasi web, pembangunan web moden telah menjadi kemahiran penting. Banyak rangka kerja dan alatan tersedia untuk membangunkan aplikasi web yang cekap, antaranya rangka kerja Yii adalah yang sangat popular. Yii ialah rangka kerja PHP berasaskan komponen berprestasi tinggi yang menggunakan corak dan teknologi reka bentuk terkini, menyediakan alatan dan komponen yang berkuasa serta sesuai untuk membina aplikasi web yang kompleks. Dalam artikel ini, kita akan membincangkan cara menggunakan rangka kerja Yii untuk membina aplikasi web. Pasang rangka kerja Yii dahulu,

Langkah-langkah untuk melaksanakan caching halaman web dan chunking halaman menggunakan rangka kerja Yii Langkah-langkah untuk melaksanakan caching halaman web dan chunking halaman menggunakan rangka kerja Yii Jul 30, 2023 am 09:22 AM

Langkah-langkah untuk melaksanakan caching halaman web dan chunking halaman menggunakan rangka kerja Yii Pengenalan: Semasa proses pembangunan web, untuk meningkatkan prestasi dan pengalaman pengguna tapak web, selalunya perlu untuk cache dan chunk halaman. Rangka kerja Yii menyediakan fungsi caching dan reka letak yang berkuasa, yang boleh membantu pembangun melaksanakan caching halaman web dan chunking halaman dengan pantas Artikel ini akan memperkenalkan cara menggunakan rangka kerja Yii untuk melaksanakan caching halaman web dan chunking halaman. 1. Hidupkan caching halaman web Dalam rangka kerja Yii, caching halaman web boleh dihidupkan melalui fail konfigurasi. Buka fail konfigurasi utama co

Buat tapak web panduan permainan menggunakan rangka kerja Yii Buat tapak web panduan permainan menggunakan rangka kerja Yii Jun 21, 2023 pm 01:45 PM

Dalam beberapa tahun kebelakangan ini, dengan perkembangan pesat industri permainan, semakin ramai pemain telah mula mencari strategi permainan untuk membantu mereka melepasi permainan. Oleh itu, mencipta laman web panduan permainan boleh memudahkan pemain mendapatkan panduan permainan, dan pada masa yang sama, ia juga boleh memberikan pemain pengalaman permainan yang lebih baik. Apabila mencipta tapak web sedemikian, kita boleh menggunakan rangka kerja Yii untuk pembangunan. Rangka kerja Yii ialah rangka kerja pembangunan aplikasi web berdasarkan bahasa pengaturcaraan PHP. Ia mempunyai ciri kecekapan tinggi, keselamatan dan kebolehskalaan yang kukuh, serta boleh membantu kami mencipta panduan permainan dengan lebih cepat dan cekap.

Perisian tengah rangka kerja Yii: menyediakan sokongan storan data berbilang untuk aplikasi Perisian tengah rangka kerja Yii: menyediakan sokongan storan data berbilang untuk aplikasi Jul 28, 2023 pm 12:43 PM

Perisian tengah rangka kerja Yii: menyediakan sokongan storan data berbilang untuk aplikasi Pengenalan Middleware (perisian tengah) ialah konsep penting dalam rangka kerja Yii, yang menyediakan sokongan storan data berbilang untuk aplikasi. Middleware bertindak seperti penapis, memasukkan kod tersuai antara permintaan dan respons aplikasi. Melalui perisian tengah, kami boleh memproses, mengesahkan, menapis permintaan, dan kemudian menyerahkan hasil yang diproses kepada perisian tengah atau pengendali akhir yang seterusnya. Middleware dalam rangka kerja Yii sangat mudah digunakan

Yii Framework Middleware: Tambahkan keupayaan pengelogan dan penyahpepijatan pada aplikasi anda Yii Framework Middleware: Tambahkan keupayaan pengelogan dan penyahpepijatan pada aplikasi anda Jul 28, 2023 pm 08:49 PM

Perisian tengah rangka kerja Yii: Tambah keupayaan pengelogan dan penyahpepijatan pada aplikasi [Pengenalan] Semasa membangunkan aplikasi web, biasanya kami perlu menambah beberapa ciri tambahan untuk meningkatkan prestasi dan kestabilan aplikasi. Rangka kerja Yii menyediakan konsep perisian tengah yang membolehkan kami melaksanakan beberapa tugas tambahan sebelum dan selepas aplikasi mengendalikan permintaan. Artikel ini akan memperkenalkan cara menggunakan fungsi perisian tengah bagi rangka kerja Yii untuk melaksanakan fungsi pengelogan dan penyahpepijatan. [Apakah middleware] Middleware merujuk kepada pemprosesan permintaan dan respons sebelum dan selepas aplikasi memproses permintaan.

Cara menggunakan pengawal untuk mengendalikan permintaan Ajax dalam rangka kerja Yii Cara menggunakan pengawal untuk mengendalikan permintaan Ajax dalam rangka kerja Yii Jul 28, 2023 pm 07:37 PM

Dalam rangka kerja Yii, pengawal memainkan peranan penting dalam memproses permintaan. Selain mengendalikan permintaan halaman biasa, pengawal juga boleh digunakan untuk mengendalikan permintaan Ajax. Artikel ini akan memperkenalkan cara mengendalikan permintaan Ajax dalam rangka kerja Yii dan memberikan contoh kod. Dalam rangka kerja Yii, pemprosesan permintaan Ajax boleh dijalankan melalui langkah-langkah berikut: Langkah pertama ialah mencipta kelas pengawal (Pengawal). Anda boleh mewarisi kelas pengawal asas yiiwebCo yang disediakan oleh rangka kerja Yii

Sulitkan dan nyahsulit data sensitif menggunakan perisian tengah rangka kerja Yii Sulitkan dan nyahsulit data sensitif menggunakan perisian tengah rangka kerja Yii Jul 28, 2023 pm 07:12 PM

Menyulitkan dan menyahsulit data sensitif menggunakan perisian tengah rangka kerja Yii Pengenalan: Dalam aplikasi Internet moden, privasi dan keselamatan data adalah isu yang sangat penting. Untuk memastikan bahawa data sensitif pengguna tidak boleh diakses oleh pelawat yang tidak dibenarkan, kami perlu menyulitkan data ini. Rangka kerja Yii memberikan kami cara yang mudah dan berkesan untuk melaksanakan fungsi menyulitkan dan menyahsulit data sensitif. Dalam artikel ini, kami akan membincangkan cara untuk mencapai ini menggunakan perisian tengah rangka kerja Yii. Pengenalan kepada rangka kerja Yii Rangka kerja Yii ialah rangka kerja PHP berprestasi tinggi.

See all articles