問題描述

為了獲得更多的 WordPress 的經驗,我深入其代碼基礎來研究其內部工作及其工作流程,當我看到這一點時,我感到非常驚訝:

  1. 他們實施 register_globals(摘自 wp-includes /class-wp.php):

     // The query_vars property will be extracted to the GLOBALS. So care should
     // be taken when naming global variables that might interfere with the
     // WordPress environment.
     function register_globals() {
        global $wp_query;
        // Extract updated query vars back into global namespace.
        foreach ( (array) $wp_query->query_vars as $key => $value) {
            $GLOBALS[$key] = $value;
        }
    
  2. 它們依賴於魔術引號 (從 wp-includes /functions.php 發出) 。在調用此函數之前,magic_quotes_gpc 在引導時被關閉):

    function add_magic_quotes( $array ) {
        foreach ( (array) $array as $k => $v ) {
        if ( is_array( $v ) ) {
            $array[$k] = add_magic_quotes( $v );
        } else {
                $array[$k] = addslashes( $v );
        }
    
  3. 它們依賴於 addslash(但是從 2.8.0 起,他們還引入了 mysql_real_escape_string,但是使用 addslashes()_weak_escape()函數仍然存在於 wpdb 類中)UPDATE:我看到他們通過使用 sprintf()和自定義放置器來模擬準備好的語句,所以查詢應該是安全的認為。仍然我很困惑,為什麼他們至少不提供 mysqli,所有的檢測 Mysql 和 PHP 版本發生在引導序列的早期。

現在,從 year-long 的經驗中我學到了很多東西,特別是上述三個功能都是”deprecated”,顯示安全問題,被許多人驚恐地看着。

但 WP 必須有理由使用它們。如果有真正的安全問題,或者有時候他們的使用在傳聞和虛假的説服中太多了,我想從更有經驗的程序員那裏知道。我知道 magic_quotes 是過去的遺產,對於 addslash 也可以這樣説 (至少用於數據庫的時候),但是在發問之前,我發現許多網站都在談論在 mysql_real_escape_string() 上使用 addslashes() 。

我有興趣瞭解為什麼使用這些功能很差的功能的清晰詳細的原因; WordPress 多年來取得了許多改進,處理不同的方面,但這些功能仍然被使用; 因此,我正在尋找一個具體的解釋,積極的方面,以某種方式超越負面的,並證明使用這些功能。

我不是在尋找意見 (我完全知道他們在這裏是偏執的),也不是我對 Wordpress 的憤怒,我希望這是清楚的。我只想知道為什麼許多 php 程序員認為這些功能”bad”,而一個像 Wordpress 這樣的世界級巨頭,現在在第三版,仍然使用它們。

這是為了兼容不同的服務器和 php 版本? (他們檢查非常耳朵,但是) 。有一些我想念的功能,他們可以在一個如 WordPress(或一般) 的環境中有多重要?老實説,我很困惑

最佳解決方案

(WordPress Open Tickets over Time)

不要依靠 Wordpress 代碼庫對 PHP 編碼中的良好做法或現行標準做假設。我在説這是一個在更長一段時間內發生了 wordpress 發展的人。

WordPress 代碼庫大約是 10 歲,它的遺留代碼 [1] 。該程序不能在 code-level 上發展,因為這樣,所以你發現很多解決方案已經解決了現在好多了。

只要講這個故事:PHP 有魔術報價。 WordPress 開發人員認為這是有用的。所以對於沒有配置的那些主機,他們添加了它。結束希望經常和在不同地方削減輸入數據的代碼。簡單的是,現在,由於 (超級) 全局變量在幾乎無處不在的情況下引入靜態全局狀態,所以現在他們不能輕易地將其改變為適當的輸入處理和消毒。

你不能輕易地重構這樣的代碼。

相同的數據庫類。它具有悠久的歷史,最初基於 ezSQL 的早期版本。當時沒有 mysql_real_escape_string,當它被介紹時,WP 開發人員的問題是並不是所有的安裝基礎都支持它。

所以不要懷疑你在 Wordpress 代碼中找到的編碼實踐。你將會學到如何在幾年前完成的工作,以及多少或更少的過時的 PHP 版本。不久之前,Wordpress 轉為 PHP 5 。

  • 向後兼容性

  • 瞄準大量 (技術上或多或少過時的) 主機。

  • 不要打破有缺陷的工作。

這可能不是您的優先事項列表 (希望),項目在這裏有很多不同。不管單獨使用遺留 code-base 如何設置項目優先級都是一種負擔。 WordPress 只是一個例子。


[1] 看到 WordPress 的里程碑:早期項目時間表 (約 2000 年至 2005 年))

次佳解決方案

補充 @tom 答案。

魔術報價

自動解析整個條目並添加魔術引號都是創建錯誤和無用的。

  • 無用,因為您無法依靠魔術引號來保護您的輸入 (multy-bytes 編碼錯誤 SQL 注入是一個例子) 。因此,在將數據保存到數據庫之前,需要應用一個實際的過濾器

  • 創建錯誤:如果您需要在數據庫中保存之前真正轉義數據庫,那麼您必須檢查它是否已經被轉義 (並且這個設置存在的簡單事實可能由託管環境執行,這樣您必須檢查此設置是否為設置或不設置) 。

  • 創建錯誤:用户發送的所有數據並不總是專用於數據庫存儲。逃避它可能會破壞內容,想想一個 json 內容,甚至文件內容與危險的 magic_quote_runtime

  • 創建錯誤:所有數據庫存儲不會以相同的方式轉義引號…

那麼為什麼?為什麼我們在 CMS 中看到這樣的功能?

  • 看到這裏是一個 add_magic_quotes 功能,可以在專用陣列上使用,也可能不在_GET 或_POST 上。但實際上這個功能只是使用 addslashes 而不是數據庫專用功能,這使得它非常糟糕。

  • 主機提供商可能會強制執行自動魔術引用的事實是 CMS 開發人員的噩夢。您可以檢測到它,並告訴用户您拒絕運行,或者您必須管理內容可能或可能不是 magically-addslahed … 並將每個人都處於相同狀態的事實,則在此功能中運行 non-addslashed 內容至少每個人都處於同一 (壞) 狀態。

  • 從 Wordpress 中可以看到的,在 wp_insert_post 中執行保存 stripslahes_deep 之前。通常在將數據發送到 wp_insert_post 之前,從 Db 提取的數據執行 add_magic_quotes 。這可能我認為問題是有效地刪除它們之前添加斜槓… 可能是因為在保存之前發生的消除過濾器預期內容與斜槓,或者也許是因為沒有人記住為什麼代碼以這種方式運行:-)

register_globals

似乎這是在 wordpress 中實現註冊表模式的方法… 他們希望使代碼變得簡單易懂,並允許一種簡單的方式來訪問諸如查詢或帖子的 important 對象。而面向對象的 Registry 類不是簡單的 PHP 方式,$_GLOBALS 數組已經是現有的註冊表。

擁有註冊表是應用程序中完全有效的東西。只有當您允許某些用户輸入覆蓋您的有效安全輸入時,register_global 才是危險的。當然,只有在 $_GLOBALS 在其他地方 (或使用 global 關鍵字) 進行此安全輸入。

這裏功能中的危險部分是您提取的功能的一部分,$query->query_vars 上的循環。您將必須跟蹤呼叫,以查看用户注入的密鑰是否可以通過 wp_parse_args 並在該功能中結束。但這個功能的下一部分是為幾個對象修復 $_GLOBALS 內容:

$GLOBALS['query_string'] = $this->query_string;
$GLOBALS['posts'] = & $wp_query->posts;
$GLOBALS['post'] = (isset($wp_query->post)) ? $wp_query->post : null;
$GLOBALS['request'] = $wp_query->request;

所以至少這些全局變量不能被用户輸入覆蓋並且是安全的。

所以這些功能不好。但是,如果您瞭解他們的工作以及您需要做什麼來防止不良影響,您可以使用它們。而當您想為開發人員實施一個簡單的框架時,可以在非常寬的環境中使用,您有時需要使用它們。

但是肯定這是一個糟糕的做法,你肯定會發現使用 $ _GLOBALS 錯誤的方式或濫用 add_magic_quotes to data pulled from db wordpress 概念的壞 wordpress 插件。但是,Zend Framework CMS 將有多年才能獲得如此大量的貢獻。

第三種解決方案

魔術報價

The following text is taken from PHP.net

http://www.php.net/manual/en/security.magicquotes.why.php

There is no reason to use magic quotes because they are no longer a supported part of PHP. However, they did exist and did help a few beginners blissfully and unknowingly write better (more secure) code. But, when dealing with code that relies upon this behavior it’s better to update the code instead of turning magic quotes on. So why did this feature exist? Simple, to help prevent SQL Injection. Today developers are better aware of security and end up using database specific escaping mechanisms and/or prepared statements instead of relying upon features like magical quotes.

addslashes()vs mysql_real_escape_string()

您應該使用 mysql_real_escape_string()的原因是因為它是一個”MySQL function”,是專門為在 mysql 查詢執行之前轉義用户輸入而創建的,而 addslashes()是一個”PHP function” 。這可能聽起來有點奇怪,但兩者之間有一個重要的區別,它與使用單和 multi-byte 字符有關。您仍然可以註冊數據庫受保護的 addslashes 功能,但注入數據庫受 mysql_real_escape_string 保護是非常困難的。你可以閲讀更多關於它的 HERE

註冊全局

您不應該使用 register_globals 的原因是因為變量可供所有人訪問,這意味着在以下示例中,您可以將 $ access 設置為 true,如果尚未初始化

<?php

if (isAuthenticated()) { $access = true; }

if ($access == true) {
  include(controlpanel.php);
}

?>

上面的代碼會給你 sh#!負載的問題,但如果我們初始化變量,首先添加以下到頁面的頂部

$access = false;

即使我們有 register_globals,我們也應該很好

所以,如果 Wordpress 團隊已經初始化了所有變量 (他們可能擁有的),那麼你不必擔心使用全局變量。

結論

這是絕對不好的做法,使用這 3 個功能/功能,我永遠不會自己做。您確定使用最新版本的 Wordpress 嗎?像有人評論説,如果你使用最新版本,那是因為懶惰,或者更糟糕的是它仍然在那裏。我永遠不會使用 Wordpress,除了不需要很多安全性的博客以外的任何東西。

第四種方案

WordPress 的。我花了很多不眠之夜試圖回答唯一的一個問題:”Why??”

由於我遇到了源代碼,所以我討厭它。太可怕了讓我的帖子 (以及聲譽) 也將被微調,但它是真實的。

它沒有核心有一個垃圾的代碼而不是核心。它提醒了 php3 。在這裏使用了大量無關和不統一的功能。 「複製和粘貼」 – 在 wordpress 中使用的唯一一種設計模式。

是的,仿效使用準備好的語句。但是為什麼他們不使用 PDO,還是 mysqli?他們已經將幾乎所有的 PDO 功能進行了複製,但是卻沒有使用它。使用 mysqli 代替 mysql 需要更少的努力。

他們使用 myql_real_escape_string 。但是還有一些像 protect_string_stronglyprotect_string_weakly 這樣的東西。不僅僅有一個功能 – do_not_protect_string_i_believe_my_users

全局變量 – 是 wordpress 的哲學。 「如果我們不知道如何改變這個 var,我們會把它標記為全局變量,每個人都會高興。」 – 這是開發人員在開發 hellpress 時想到的 wordpress 開發者。

每個新版本都包含了很多新的設計,它們添加了新的默認主題,它們將管理區域中的背景顏色從 #ccc 更改為 #cdcdcd,它們在管理區域中使用下拉菜單而不是通配符。而且真棒但是它們並沒有改進其代碼。

你看過 WP “core” 的評論嗎?沒有?我做了他們是”awesome” 。像 「這個功能叫什麼」 呢?讓我們來吧,以防萬一。 「或 「不要在新版本中硬編碼」 。等等。

問題”Why?” 的唯一答案是:「因為它的工作,如果它的工作不要碰它!!!」

wordpress.org 是世界上最受歡迎的網站之一。為什麼?因為沒有人能夠理解 wordpress 的邏輯。每個人每次都需要在論壇上提出問題,或者閲讀這些法規。

我希望你明白我的觀點。

第五種方案

沒有比 magic_quotes 提到 PHP 文檔更好的方法來回答他們為什麼不好。

另請注意:

This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.


那麼為什麼 Wordpress 仍然使用魔術報價?

WordPress minimum requirements 使用 PHP 4.3 。是的,這絕對是向後兼容的原因。

其他功能怎麼樣?

我老實説不確定依靠超級全局是一個非常壞的主意。這是 Wordpress 開發團隊的簡單懶惰。也許他們有更重要的問題需要解決。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。