問題描述

這些天最常見的安全最佳做法之一似乎是將 wp-config.php 的一個目錄移動到高於 vhost 的檔案根目錄。我從來沒有真正找到一個很好的解釋,但我假設它是最小化 webroot 中的惡意或感染指令碼的風險從閱讀資料庫密碼。

但是,您仍然必須讓 WordPress 訪問它,因此您需要擴充套件 open_basedir 以將檔案根目錄上方的目錄包括在內。這不僅僅是打敗整個目的,還可能會將伺服器日誌,備份等暴露給攻擊者?

或者是隻是試圖阻止 wp-config.php 將被顯示為任何請求 http://example.com/wp-config.php 的任何人的情況的技術,而不是由 PHP 引擎解析?這似乎是一個非常罕見的事情,它不會超過暴露日誌/備份/ etc 到 HTTP 請求的缺點。

也許可以將它移動到某些主機設定中的檔案根目錄外,而不會暴露其他檔案,但不能在其他設定中?


結論:在這個問題上經過很多的 back-and-forth,出現了兩個答案,我認為應該被認為是權威的。亞倫·亞當斯 (Aaron Adams) 表示贊成移動 wp-config,克里斯蒂安 (Joe Adams) 對此表示反感。這些是你應該閱讀的兩個答案,如果你是新的執行緒,不想閱讀整個事情。其他答案是冗餘或不準確的。

最佳解決方案

簡答:是的

這個問題的答案是一個明確的肯定,否則說完全是不負責任的。


長答案:一個 real-world 的例子

讓我提供一個非常真實的例子,從我真正的伺服器,移動 wp-config.php 外面的 Web 根,專門阻止其內容被捕獲。

錯誤:

看看這個描述在 Plesk 的一個錯誤 (固定在 11.0.9 MU#27):

Plesk resets subdomain forwarding after syncing subscription with hosting plan (117199)

聽起來無害,對吧?

嗯,這是我做了什麼來觸發這個錯誤:

  1. 設定子域以重定向到另一個 URL(例如 site.staging.server.comsite-staging.ssl.server.com) 。
  2. 更改訂閱的服務計劃 (例如其 PHP 配置) 。

當我這樣做時,Plesk 將子域重置為預設值:為~/httpdocs/的內容提供服務,沒有口譯員 (例如 PHP) 的活動。

我沒有注意到。數週。

結果:

  • 在 Web 根目錄中使用 wp-config.php,對/wp-config.php 的請求將下載 WordPress 配置檔案。
  • 使用 wp-config.php 在 Web 根外部,對/wp-config.php 的請求下載完全無害的檔案。真正的 wp-config.php 檔案無法下載。

因此,顯而易見的是,在網頁外移動 wp-config.php 在現實世界中具有真正的安全優勢。


如何將 wp-config.php 移動到伺服器上的任何位置

WordPress 將自動在您的 wp-config.php 檔案的 WordPress 安裝上方看到一個目錄,所以如果你已經移動了它,那麼你就完成了!

但是如果你把它移到別的地方呢?簡單。在 WordPress 目錄中使用以下程式碼建立一個新的 wp-config.php

<?php

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

/** Location of your WordPress configuration. */
require_once(ABSPATH . '../phpdocs/wp-config.php');

(請務必將上述路徑更改為重定位的 wp-config.php 檔案的實際路徑。)

如果遇到 open_basedir 的問題,只需在 PHP 配置中新增 open_basedir 指令的新路徑:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

而已!


提出相反的論據

在網頁外移動 wp-config.php 的所有爭論都取決於假設。

引數 1:如果停用 PHP,它們已經存在

The only way someone is going to see that contents of
[wp-config.php] is if they circumvent your servers PHP interpreter…
If that happens, you’re already in trouble: they have direct access to
your server.

FALSE:我上面描述的場景是錯誤配置的結果,而不是入侵。

引數 2:意外的停用 PHP 是罕見的,因此是微不足道的

If an attacker has enough access to change the PHP handler, you’re
already screwed. Accidental changes are very rare in my experience,
and in that case it’d be easy to change the password.

FALSE:我上面描述的場景是一個常見的伺服器軟體中的錯誤的結果,影響了一個常見的伺服器配置。這幾乎不是”rare”(此外,安全意味著擔心罕見的情況) 。

WTF:如果在入侵期間收到敏感資訊,入侵後更改密碼幾乎不會有幫助。真的,我們仍然認為 WordPress 僅用於休閒部落格,而攻擊者只對汙名感興趣嗎?我們擔心保護我們的伺服器,而不僅僅是在有人進入後恢復。

引數 3:拒絕訪問 wp-config.php 是足夠好的

You can restrict access to the file via your virtual host config or
.htaccess – effectively limiting outside access to the file in the
same way that moving outside the document root would.

FALSE:想象一下虛擬主機的伺服器預設值是:沒有 PHP,沒有.htaccessallow from all(在生產環境中幾乎不常見) 。如果您的配置在例行操作中以某種方式重置 (例如,面板更新),則所有操作都將恢復為預設狀態,並顯示出來。

如果您的安全模型在設定意外重置為預設設定時失敗,則需要更多的安全性。

WTF:為什麼有人特意推薦更少的安全層?昂貴的汽車不只是有鎖; 他們還有鬧鐘,固定裝置和 GPS 追蹤器。如果有什麼值得保護的話,做對吧。

引數 4:未經授權訪問 wp-config.php 是沒有什麼大不了的

The database information is really the only sensitive stuff in
[wp-config.php].

FALSE:認證金鑰和鹽可用於任何數量的潛在劫持攻擊。

WTF:即使資料庫憑據是 wp-config.php 中的唯一的事情,您也應該害怕攻擊者手中。

引數 5:在 Web 根外部移動 wp-config.php 實際上使伺服器不太安全

You still have to let WordPress access [wp-config.php], so you need
to expand open_basedir to include the directory above the document
root.

FALSE:假設 wp-config.phphttpdocs/中,只需將其移動到../phpdocs/,並將 open_basedir 設定為僅包含 httpdocs/phpdocs/。例如:

open_basedir = "/var/www/vhosts/example.com/httpdocs/;/var/www/vhosts/example.com/phpdocs/;/tmp/"

(記住要始終包括/tmp/或您的使用者 tmp/目錄,如果您有) 。


結論:配置檔案應始終始終位於 Web 根外部

如果你關心安全性,你將把 wp-config.php 移到你的網頁之外。

次佳解決方案

最重要的是 wp-config.php 包含一些敏感資訊:您的資料庫使用者名稱/密碼等。

所以這個想法:把它移到檔案根目錄之外,你不必擔心任何事情。攻擊者永遠無法從外部來源訪問該檔案。

然而,這是擦除:wp-config.php 從來沒有實際列印任何東西到螢幕。它只定義了在整個 WP 安裝過程中使用的各種常量。因此,有人會看到該檔案的內容是唯一的方法是如果他們繞過您的伺服器 PHP 直譯器 – 他們將.php 檔案渲染為純文字。如果發生這種情況,您已經遇到了麻煩:他們可以直接訪問您的伺服器 (也可能是 root 許可權),並可以做任何他們喜歡的操作。

我將繼續說,從安全形度來看,將 wp-config 移到檔案根目錄之外沒有任何好處 – 由於上述原因和這些原因:

  1. 您可以透過虛擬主機配置或.htaccess 限制對該檔案的訪問 – 有效地限制對檔案的訪問許可權與檔案根目錄外的相同方式
  2. 您可以確保 wp-config 上的檔案許可權嚴格,以防止任何沒有足夠許可權的使用者讀取檔案,即使他們透過 SSH 獲取 (限制) 訪問伺服器。
  3. 您的敏感資訊,資料庫設定僅在單個站點上使用。所以即使攻擊者獲得訪問該資訊,唯一會影響的站點是 wp-config.php 檔案所屬的 WordPress 安裝。更重要的是,該資料庫使用者只具有讀取和寫入該 WP 安裝資料庫的許可權,也沒有其他的許可權 – 無許可權授予其他使用者許可權。換句話說,如果攻擊者可以訪問您的資料庫,這只是一個從備份恢復的問題 (請參閱第 4 點) 並更改資料庫使用者
  4. 你經常備份。通常是一個相對的術語:如果你每天釋出 20 篇文章,你最好每天或每隔幾天備份。如果您每週釋出一次,每週備份一次可能就足夠了。
  5. 您的站點受版本控制 (like this),這意味著即使攻擊者獲得訪問許可權,也可以輕鬆地檢測程式碼更改並將其回滾。如果攻擊者可以訪問 wp-config,那麼他們可能會搞砸別的東西。
  6. 資料庫資訊真的是 wp-config 中唯一敏感的東西,因為你很小心 (參見第 3 點和第 4 點),這不算什麼。任何時候都可以改變鹽等。發生的唯一事情是使使用者的 Cookie 無效。

對我來說,將 wp-config 從檔案中移除,這是一個非常棒的人。

第三種解決方案

我認為馬克斯是一個知識淵博的答案,而這是故事的一面。 WordPress Codex has more advise

Also, make sure that only you (and the web server) can read this file
(it generally means a 400 or 440 permission).

If you use a server with .htaccess, you can put this in that file (at
the very top) to deny access to anyone surfing for it:

<files wp-config.php>
order allow,deny
deny from all
</files>

請注意,在 wp-config.php 上設定 400 或 440 的許可權可能會阻止外掛寫入或修改它。例如,一個真正的例子是快取外掛 (W3 Total Cache,WP Super Cache 等) 在這種情況下,我將使用 600(/home/user 目錄中的檔案的預設許可權) 。

第四種方案

肯定是

當您將 wp-config.php 移動到公共目錄之外時,當 php 處理程序惡意 (或意外!) 更改時,您可以使用瀏覽器保護它免受閱讀。

當伺服器幾乎不受跛腳管理員的錯誤感染時,可以讀取您的 DB 登入名/密碼。給管理員一個罰款,並獲得一個 better-tended 和更可靠的伺服器主機。雖然這可能會更貴。

第五種方案

有人要我們照看,我會在這裡回答。

是的,從您的站點的根目錄隔離您的 wp-config.php 有安全的好處。

1-如果您的 PHP 處理程序以某種方式被破壞或修改,您的資料庫資訊將不會被公開。是的,我在伺服器更新期間看到這種情況在共享主機上發生了幾次。是的,該網站將在此期間被破壞,但您的密碼將是完整的。

2-最佳做法總是建議從資料檔案中隔離配置檔案。是的,這是很難用 WordPress(或任何網路應用程式),但移動它做一點隔離。

3-記住 PHP-CGI 漏洞,其中任何人都可以將。-s 傳遞給檔案並檢視源。 http://www.kb.cert.org/vuls/id/520827

最後,這些都是細節細節,但它們有助於最大限度地降低風險。特別是如果您處於共享環境中,任何人都可以訪問您的資料庫 (所有他們需要的是使用者/通行證) 。

但是請不要讓小心的分心 (過早的最佳化) 得到真正需要使網站正確安全的前提:

1-始終保持更新

2-使用強密碼

3-限制訪問 (透過許可權) 。我們在這裡有一個帖子:

 http://blog.sucuri.net/2012/08/wordpress-security-cutting-through-the-bs.html

謝謝,

第六種方案

我只是想澄清一下,為了爭論,移動你的 wp_config.php 檔案並不一定意味著你必須把它移動到父目錄。假設你有一個結構,如/ root / html,其中 html 包含 WP 安裝和所有的 HTML 內容。而不是將 wp_config.php 移動到/ root,您可以將其移動到/ root / secure … 之外,這兩者都在 html 目錄之外,也不在伺服器根目錄中。當然,您需要確保 php 可以在此安全資料夾中執行。

由於 WP 無法配置為在同級資料夾 (如/ root / secure) 中查詢 wp_config.php,因此您必須採取額外的步驟。我將 wp_config.php 放在/ root / html 中,並刪除敏感部分 (資料庫登入名,salt,表字首),並將它們移動到一個名為 config.php 的單獨檔案中。然後,您將 PHP include 命令新增到您的 wp_config.php,如下所示:include('/home/content/path/to/root/secure/config.php');

這本質上是我在我的設定中所做的。現在,基於上述討論,我還在評估是否有必要甚至是一個好主意。但我只是想補充說,上述配置是可能的。它不會暴露您的備份和其他根檔案,只要安全資料夾沒有設定自己的公共 URL,它是不可瀏覽的。

此外,您可以透過在其中建立.htaccess 檔案來限制對安全資料夾的訪問:

order deny,allow
deny from all
allow from 127.0.0.1

第七種方案

有很多不好的書面主題和外掛,允許 atatckers 注入程式碼 (記住與 Timthumb 的安全問題) 。如果我是攻擊者,為什麼要搜尋 wp-config.php?只需注入這段程式碼:

var_dump( DB_NAME, DB_USER, DB_PASSWORD );

您可以嘗試隱藏您的 wp-config.php 。只要 WordPress 將所有敏感資訊全域性訪問,隱藏 wp-config.php 就沒有任何好處。

wp-config.php 的不好的部分不是它儲存敏感資料。不好的部分是將敏感資料定義為全域性可訪問常數。

更新

我想澄清 define()的問題,為什麼將敏感資料定義為全域性常量是一個壞主意。

有很多方法來攻擊網站。腳註注入只是打破網站的一種方式。

假設伺服器有一個漏洞,讓攻擊者訪問記憶體轉儲。攻擊者會在記憶體中找到所有變數的所有值。如果你定義一個全域性可訪問的常量,它必須保持在記憶體中,直到指令碼結束。建立一個變數而不是一個常量,在不再需要該變數的情況下,很可能垃圾回收器會覆蓋 (或釋放) 記憶體。

保護敏感資料的更好方法是在使用它們後立即刪除它們:

$db_con = new stdClass();
$db_con->db_user = 'username';
$db_con->password = 'password';
$db_con->host = 'localhost';

$db_handler = new Database_Handler( $db_con );

$db_con = null;

使用敏感資料後,分配給 null 會覆蓋記憶體中的資料。攻擊者必須在 $db_con 包含敏感資料的時刻獲取記憶體轉儲。這在上面的例子中是非常短的時間 (如果 Database_Handler 類不儲存它的副本) 。

參考文獻

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