問題描述

這些天最常見的安全最佳做法之一似乎是將 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。