問題描述

為了獲得更多的 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。