WordPress wp-config 加固與 SALT 金鑰設定

WordPress wp-config.php 是整個網站最敏感的一支檔案。資料庫帳號密碼、主機位置、加密金鑰,全部寫在這裡。攻擊者掃描網站時,第一個鎖定的目標往往就是它,只要讀到內容,等於拿到後門鑰匙。

WordPress wp-config.php 安全做得好不好,直接決定了網站被攻破的難度。偏偏多數人裝完站就再也沒碰過這支檔案,金鑰沿用安裝時的預設、檔案權限大開、放在公開目錄任人存取。這篇會把該動的設定一條一條講清楚,從安全金鑰(SALT)的正確生成與輪替時機,到檔案位置、權限、存取封鎖,以及幾個多數教學漏掉的實戰陷阱。

wp-config.php 裡到底放了哪些敏感資料

這支檔案存的是 WordPress 啟動所需的全部核心設定,一旦外洩,網站幾乎等於門戶洞開。具體包含四類資料。

  • 資料庫連線資訊:資料庫名稱、使用者帳號、密碼、主機位址。攻擊者拿到這組,就能直接連線資料庫撈出全站使用者、訂單、會員資料。
  • 安全金鑰與 SALT:八組加密字串,用來簽署登入 cookie 與 nonce 權杖。外洩後攻擊者可能偽造登入憑證,繞過密碼直接取得管理員身分。
  • 資料表前綴:預設是 wp_,決定資料庫裡每張表的名稱。
  • 進階常數:除錯模式、自動更新、檔案編輯開關、SSL 強制等行為設定。

正因為一支檔案集中了這麼多要害,加固 wp-config.php 的投資報酬率遠高於其他單點防護。下面從最常被忽略、卻最致命的金鑰設定開始。

安全金鑰與 SALT 是什麼,為什麼非設不可

安全金鑰(Security Keys)與 SALT 是一組隨機字串,WordPress 用它們來雜湊並加密存在瀏覽器 cookie 與 session 權杖裡的資料。它們不是密碼,作用是讓登入 cookie 與表單 nonce 難以被猜測或偽造。

一個正常的 WordPress 站會有八組值,成對運作。

常數名稱 負責的對象
AUTH_KEY、AUTH_SALT 一般驗證 cookie
SECURE_AUTH_KEY、SECURE_AUTH_SALT HTTPS 加密驗證 cookie
LOGGED_IN_KEY、LOGGED_IN_SALT 已登入狀態 cookie
NONCE_KEY、NONCE_SALT 表單與動作的 nonce 權杖

運作原理是這樣:使用者登入後,WordPress 用這些金鑰把登入狀態簽成一個加密 cookie 存進瀏覽器。下次造訪時,WordPress 用同一組金鑰驗證 cookie 是不是自己簽的。沒有強隨機的 SALT,攻擊者就算攔截到一個 session cookie,也有機會反推出規律、進而偽造出有效的管理員 cookie,直接劫持後台。

要釐清一個常見誤解:金鑰與 SALT 的保護範圍很窄。它們只決定「某個 cookie 或權杖該不該被信任」,不會清除惡意程式、不會擋暴力破解、也救不了一個密碼早就外洩的管理員帳號。它是登入信任鏈的一環,不是萬靈丹。

最危險的情況是金鑰根本沒設。如果打開 wp-config.php 看到的還是 put your unique phrase here 這種預設佔位字串,代表網站等於沒有 SALT 保護,整個驗證層暴露在彩虹表與暴力破解之下,這是必須立刻處理的漏洞。

怎麼正確生成 SALT,三種方法的取捨

生成 SALT 的黃金準則只有一句:用密碼學等級的隨機來源,每組值都不重複、夠長(建議 64 字元以上),而且絕對不要自己亂編。常見有三種做法,各有取捨。

第一種,官方 secret-key API。 WordPress.org 提供一個官方的 secret-key 產生端點(路徑為 api.wordpress.org 下的 secret-key 服務),每次造訪都會即時產生一整組八行的 define() 設定,直接複製貼進 wp-config.php 取代舊值即可。這是最普及的方法,缺點是你等於把金鑰交給第三方伺服器生成,連線必須走 HTTPS。萬一伺服器的 TLS 憑證鏈有問題,理論上有在不安全連線下接收金鑰的風險。

第二種,瀏覽器本機生成。 有些工具用瀏覽器內建的 crypto.getRandomValues() 在本機產生金鑰,金鑰從頭到尾不經過網路傳輸,只存在瀏覽器記憶體裡,直到你複製貼上。從不外傳這點來看,安全性最高。

第三種,WP-CLI 指令。 如果你的網站能用 SSH 連入且裝了 WP-CLI,一行指令就能在伺服器端直接重新生成並寫入金鑰。

wp config shuffle-salts

這個方法最適合自動化流程或部署管線,前提是你已經習慣用 SSH 管理網站,並且清楚金鑰是不是存在標準位置(有些主機或進階設定會把金鑰放到環境變數或另一支設定檔)。

不論用哪種方法,產出的八組值都要彼此不同。把同一個字串重複貼到多個常數,等於讓 SALT 機制失去意義。

手動替換 SALT 的步驟與必踩底線

手動替換是最通用的做法,適合任何能安全編輯 wp-config.php 的情境。動手前先記住一條鐵律:這支檔案少一個引號、漏一個括號,整個網站立刻白畫面,所以務必先備份再改。

步驟拆解如下。

  1. 取得編輯權限:透過 SFTP、SSH 或主機控制台的檔案管理員連到網站根目錄,找到 wp-config.php。
  2. 備份現有檔案:把原始 wp-config.php 複製一份留底,改壞了能立刻還原。
  3. 定位金鑰區塊:找到標示為「Authentication Unique Keys and Salts」的段落,裡面就是八行 define()
  4. 整段替換:把生成好的八組新值貼上,確認每一行都有對應的常數名稱、每個值都唯一。

替換後的格式長這樣,引號與分號一個都不能少。

define('AUTH_KEY',         '這裡放第一組唯一隨機字串');
define('SECURE_AUTH_KEY',  '這裡放第二組唯一隨機字串');
define('LOGGED_IN_KEY',    '這裡放第三組唯一隨機字串');
define('NONCE_KEY',        '這裡放第四組唯一隨機字串');
define('AUTH_SALT',        '這裡放第五組唯一隨機字串');
define('SECURE_AUTH_SALT', '這裡放第六組唯一隨機字串');
define('LOGGED_IN_SALT',   '這裡放第七組唯一隨機字串');
define('NONCE_SALT',       '這裡放第八組唯一隨機字串');

有兩件事特別容易出錯,這裡標出來。第一、不要從 WordPress 後台或外掛直接編輯 wp-config.php,這支檔案的語法錯誤會讓你連後台都進不去,得改用 FTP 或 SSH 才救得回來。第二、不要把 wp-config.php 提交進 Git 版本控制,任何能存取儲存庫的人都會看到你的正式環境金鑰,這是團隊協作時最常見的金鑰外洩管道。

什麼時候該輪替 SALT,什麼時候不必

該輪替 SALT 的判準只有一個:當舊金鑰可能已經不再私密的時候。不要因為「定期換比較安心」就排程每月、每季硬換,那只會製造干擾、解決不了真正的風險。

明確該換的情境有這幾種。

  • 網站被入侵或疑似被入侵:清除惡意程式之後輪替,讓攻擊者手上的舊登入 cookie 全部失效。
  • wp-config.php、資料庫備份或程式碼儲存庫曾經外洩:把外洩的金鑰當成已洩漏的密碼處理,立刻換掉。
  • 金鑰還停在預設佔位字串:形同沒有保護,馬上生成真正的隨機值。
  • 移除了某個管理員或開發者的存取權:離職交接時一併輪替,斷開他可能還握有的舊憑證。

反過來說,如果網站健康、沒有任何外洩跡象、金鑰也早就是唯一隨機值,那就把時間花在更重要的事情上:核心與外掛更新、定期備份、登入防護、兩步驟驗證、惡意程式掃描。固定排程輪替 SALT 對這類網站是「用干擾換不到多少防護」。

理由在於輪替 SALT 本質上是個範圍很廣的工具,做的是「讓所有舊 session 失效」這件事。真正能阻擋下一次攻擊的,是修補漏洞與強化登入,不是反覆替換八行字串。把輪替留給「信任已經被打破」的時刻,效果才最大。

輪替 SALT 之後,網站會發生什麼

輪替 SALT 不會改動任何使用者的帳號或密碼,它改變的是「WordPress 願意信任什麼」。換掉金鑰的當下,所有用舊金鑰簽出來的 cookie 與 nonce 全部失效,效果具體如下。

最直接的影響是所有登入中的使用者會被登出,包含你自己,所有人都得重新輸入帳密登入。這正是輪替能在事故後「踢掉攻擊者」的原因,但對使用者來說就是一次集體登出。

對單純的部落格,這只是一次幾乎無感的登出事件。但對電商、會員制、線上課程、社群這類網站,集體登出可能正好打斷使用者結帳或上課的流程,所以要挑離峰時段、規劃一個短短幾分鐘的維護窗口再動手。

還有一個少見但要注意的狀況:有些外掛會借用 WordPress 的 SALT 來加密自己儲存的密鑰,例如 API 金鑰、寄信設定、兩步驟驗證的種子碼。輪替後如果發現某個外掛的設定突然失效,先去檢查那個外掛的設定,而不是直接認定整站壞掉。

要強調的是,輪替本身完全不會造成網站停機,網站還是照常出頁面,受影響的只有既有的登入狀態。它也不能取代密碼重設與惡意程式清除:如果是入侵後處理,務必先清乾淨惡意程式再輪替,否則只要攻擊者還握有檔案讀取權限,新金鑰一存檔就立刻被讀走。

wp-config.php 該放在哪,又該設什麼權限

光把金鑰設對還不夠,檔案本身的位置與權限決定了它有多容易被外部直接讀取。這一節處理「不讓人碰到檔案」這件事。

位置上移一層目錄。可以把 wp-config.php 從網站根目錄往上移一層,放到網站公開目錄(通常是 public_htmlwww)的上層。WordPress 在根目錄找不到這支檔案時,會自動往上一層找,所以功能不受影響,但對外部請求來說,這支檔案已經不在可直接存取的範圍內。

權限收到最小。wp-config.php 存的是要害,權限該收緊。常見的做法是從最嚴格的設定起步,遇到問題再放寬。

  • 400440、只有擁有者可讀,最嚴格,部分主機環境適用。
  • 600、擁有者可讀寫,是相當穩妥的折衷,多數情況夠用。
  • 640、擁有者可讀寫、同群組可讀,在 VPS 上 web server 屬於同群組時常用這個值。

原則是依最小權限起步,真的跑出問題再逐步往上調,任何檔案都絕對不要設成 777。順帶一提,整站其他檔案的合理基準是目錄 755、檔案 644;只有 PHP 必須寫入的位置(例如 wp-content/uploads)才視需要把目錄放寬到 775、檔案 664

用 .htaccess 或 Nginx 規則徹底封鎖外部存取

就算檔案位置與權限都設好了,再加一道伺服器層的存取封鎖等於上雙保險,尤其能擋住「PHP 沒被正確解譯、原始碼被當純文字吐出」這種極端但真實存在的狀況。

如果主機跑的是 Apache 且支援 .htaccess,在檔案最上方加入這段,直接拒絕所有對 wp-config.php 的請求。

<FilesMatch "wp-config.php">
    Require all denied
</FilesMatch>

如果是 Nginx,改在站台設定的 server 區塊裡加一段 location 規則。

location ~* wp-config.php {
    deny all;
}

這道封鎖的價值在於:即使有一天伺服器設定出錯、PHP 引擎暫時不運作,wp-config.php 也不會被當成純文字檔案直接送到瀏覽器,敏感內容仍然進不了攻擊者的眼裡。

多數教學漏掉的陷阱:重新命名 wp-config.php 會吐出原始碼

這是一個極少教學提到、卻造成大量網站資料外洩的陷阱:在排錯或備份時隨手把 wp-config.php 改名,很可能讓整支檔案的原始碼被攻擊者一個 GET 請求就抓走。

原理在於 PHP 程式必須是 .php 副檔名才會被引擎解譯執行。一旦你在副檔名「後面」接上文字,例如把 wp-config.php 改成 wp-config.php.bakwp-config.good,PHP 引擎就不再把它當程式碼跑,伺服器在多數情況下會直接把檔案內容當純文字吐出來。於是裡面的資料庫帳號密碼,任何人用瀏覽器打開那個網址就看得到。

更麻煩的是攻擊者早就把這招自動化了。他們用工具大量掃描網站,對一長串常見的改名變體發出請求,例如 wp-config.bakwp-config.php.oldwp-config.php~wp-config.php.savewp-config.php.orig 等等。攻擊者不需要知道你怎麼改的,把常見命名跑一遍就行。

避開的方法很簡單:要改名就把文字加在前面,不要加在後面。 與其改成 wp-config.bak,改成 bak-wp-config.php 這種保留 .php 結尾的命名,PHP 就會正常解譯、不會吐原始碼。這條規則不只網站管理者要記住,幫忙排錯的主機商或技術支援人員同樣常犯這個錯。

還有哪些 wp-config 常數值得一併設定

除了金鑰、位置、權限,wp-config.php 還能定義幾個影響安全與資訊揭露的行為常數,加固時建議一併處理。

關閉後台檔案編輯。 WordPress 後台預設讓管理員直接線上編輯外掛與佈景主題的 PHP 檔,這條路徑一旦被取得管理員權限的攻擊者利用,就能直接植入後門。加上這兩行可以關掉。

define('DISALLOW_FILE_EDIT', true);  // 關閉佈景與外掛的線上編輯器
define('DISALLOW_FILE_MODS', true);  // 連外掛佈景的安裝與更新都一併禁止

要注意 DISALLOW_FILE_MODS 連帶會擋掉外掛更新,啟用後得改用 WP-CLI 或手動 FTP 來維護,請依自己的運維習慣斟酌。

正式環境關閉除錯顯示。 開發時開著 WP_DEBUG 很方便,但正式站若把錯誤訊息直接顯示在前台,可能洩漏路徑、外掛版本等資訊給攻擊者。正式環境建議這樣設。

define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);

強制後台走 HTTPS。 加上 define('FORCE_SSL_ADMIN', true); 可以強制所有後台與登入頁面走加密連線,避免帳密在傳輸過程被攔截。

自訂資料表前綴。 安裝時把預設的 wp_ 改成不易猜測的前綴(例如 wp_7x9k_),能稍微增加自動化 SQL injection 攻擊的難度。這是裝站時就該決定的事,既有站要改前綴牽涉資料庫改名,風險較高,沒把握就別動。

把 wp-config.php 加固變成可重複的維護節奏

WordPress wp-config.php 安全不是裝完站設一次就結束,而是該納入維護節奏的一環。真正能擋下攻擊的,從來不是某一條神奇設定,而是把幾件無聊但確實有效的小事做齊:金鑰用密碼學等級隨機值且每站唯一、檔案位置上移一層並收緊權限、伺服器層封鎖直接存取、改名時把文字加在前面、正式環境關掉除錯顯示與後台檔案編輯。

接下來的動作很明確。先打開你的 wp-config.php,確認金鑰不是預設佔位字串、檔案權限不是大開狀態;接著把這篇提到的常數逐條對照補齊。要輪替 SALT,記得先備份檔案、挑離峰時段、預告使用者會被登出。等基本盤都穩了,再把心力放到核心更新、定期備份與登入防護上,讓整個網站的防禦一層疊一層,而不是把希望全押在單一設定。

相關文章
標籤: wp-config.php, 檔案權限, 安全金鑰 SALT, 網站加固, WordPress 安全