首頁  >  文章  >  後端開發  >  為什麼在 PHP 中反序列化物件是一個壞主意?

為什麼在 PHP 中反序列化物件是一個壞主意?

WBOY
WBOY原創
2024-07-20 05:06:29748瀏覽

Why is unserializing an object in PHP a bad idea?

PHP 中的序列化是將 PHP 物件轉換為字串的一種方法。該字串可以以多種方式使用,例如將其儲存在資料庫中或將其傳遞給另一個函數。 PHP 文件表示,在傳遞 PHP 值而不丟失其類型和結構時,這非常方便。但我以前從未遇到過這個問題。可能我沒看到。

<?php
$test = new User();
$test->name = "Denzyl";
echo serialize($test);
/// Output: O:4:"User":1:{s:4:"name";s:6:"Denzyl";}

那麼,讓我們來消化一下這個字串。 o代表Object,後面的數字是物件名稱的長度。兩個字母 s 代表字串和字串名稱的長度。

當您需要將字串轉換回 PHP 時,呼叫反序列化函數並將字串作為參數傳遞。

序列化物件時,會自動呼叫兩個方法。 __serialize() 和 __sleep()。這將允許類別作者在將物件轉換為字串之前執行某些操作。
這是開門見山。但現在,讓我們專注於字串的反序列化。這意味著將字串轉換為真正的 PHP 對象,稍後可以在運行時在 PHP 程式碼中使用。

<?php

$string = 'O:8:"User":1:{s:4:"name";s:6:"Denzyl";}';
echo unserialize($string)->name;
/// Output: Denzyl

相同的功能也適用於反序列化。但這次,兩個方法是 __unserialize() 和 __wakeup()。

但為什麼這是一個壞主意呢?

在不知情的情況下使用反序列化可能會導致遠端程式碼執行。這就是為什麼他們說永遠不要相信輸入。
假設您很懶並且信任隨機輸入,並且您連接到序列化對象,這樣您就可以
更改物件內部的值。 BOOM,你可能會被駭客攻擊。

<?php
$username = $_GET['username'];
$serialized = 'O:8:"User":1:{s:4:"name";s:6:"' . $username . '";}';

我不會解釋如何為這樣的事情編寫漏洞利用程式。有些工具可以自動為您產生有效負載,您可以稱自己為腳本小子(我們都從某個地方開始)。我認識的是PHPGGC。

要了解該漏洞,您可以閱讀 OWASP 文章。
如果您之前不知道這一點,請閱讀有關漏洞的 OWASP 文章的其餘部分

我知道我還沒有解釋如何寫漏洞程式。我不認為我能比網路上的文章做得更好。但現在您知道了這一點,並且可以進行研究。

如何防止被利用?

為什麼要用這個?我不知道;我編程的時間還不夠長(大約 15 年),還沒有機會使用序列化/反序列化來解決問題。
我的解決方案太激進了。簡單的答案是。 不要在我的 PHP 專案中使用它。

本文是我為 PHP 編寫靜態分析工具的系列文章的一部分,該工具可以在幾分鐘/幾秒鐘內掃描大量項目。並尋找規則
開發人員希望在他們的專案中擁有這些內容。在撰寫本文時,我正在製定一項規則來停止
人們不再使用反序列化,它應該為下一個版本做好準備。請關注該項目,以便您在
時收到通知 我決定寫更多規則。

以上是為什麼在 PHP 中反序列化物件是一個壞主意?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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