WordPress 被駭客入侵?為什麼遷移到 Next.js + Supabase 是您最好的解決方案
我已經失去了多少次客戶來找我們,講述同樣故事的某種變化:「我們的 WordPress 網站被駭客入侵。我們清理了。它又被駭客入侵了。我們放棄了。」最後一個是一家中型電子商務公司,他們的 WooCommerce 店鋪被注入了信用卡盜取程式,隱藏在看起來合法的外掛更新內。他們洩露客戶付款資料已經三週才被發現。這不是邊緣案例。這是 WordPress 生態系的日常。
這篇文章不是為了抨擊 WordPress。它支援了大量網路,是有原因的。但在 2005 年使其易於使用的架構,在 2025 年正是使其成為自動化攻擊磁鐵的同一架構。如果你已經被駭客入侵 -- 或你厭倦了花錢在本身就是攻擊向量的安全外掛上 -- 這是你遷移到根本上更安全的東西的攻略。
目錄
- WordPress 安全問題是架構性的
- 2025 年常見的 WordPress 攻擊向量
- 為什麼無頭架構消除了整個攻擊類別
- Next.js + Supabase:以安全為優先的堆疊
- 攻擊面比較:WordPress vs 無頭
- 遷移攻略:WordPress 到 Next.js + Supabase
- 遷移後安全加固
- WordPress 安全的真實成本 vs 遷移
- 常見問題

WordPress 安全問題是架構性的
讓我清楚地說一件事:WordPress 核心團隊做了扎實的安全工作。WordPress 核心,保持最新,是合理安全的。但沒人只執行 WordPress 核心。平均 WordPress 網站安裝了 20-30 個外掛。每一個都是你沒寫的依賴,由你不認識的人維護,可以存取你的資料庫、你的檔案系統和你使用者的資料。
這裡有一件在「WordPress 安全最佳實踐」文章中一直被遺漏的事:問題不是 WordPress 網站所有者很疏忽。問題是 WordPress 的架構要求你直接在你的伺服器上安裝第三方可執行 PHP 程式碼才能獲得基本功能。這相當於給每個在你房子工作的承包商永久複製一份你房子的鑰匙。
WPScan 的漏洞資料庫在 2024 年追蹤了超過 7,900 個新 WordPress 漏洞,其中約 96% 來自外掛。Sucuri 的 2024 威脅報告發現 WordPress 佔了他們清理的所有 CMS 感染的約 95%。Patchstack 報告 2024 年 33% 的 WordPress 關鍵漏洞在披露時沒有補丁。
這些不是可以通過更好的程式碼實踐修復的錯誤。它們是架構本身固有的特性。
2025 年常見的 WordPress 攻擊向量
在我們談論修復之前,讓我們列出你實際上在防禦什麼。我個人已經分類了數十個被入侵的 WordPress 網站,這些攻擊落入可預測的模式。
通過外掛的 SQL 注入
WordPress 使用具有良好記錄的架構的 MySQL 資料庫。每個接受使用者輸入並接觸資料庫的外掛都是潛在的 SQL 注入點。$wpdb->prepare() 函數存在,但它是可選的。外掛開發者忘記它、誤用它或完全跳過它進行「簡單」查詢。
我曾經追蹤了一個注入到一個已停用 18 個月的聯絡表單外掛,但在 200,000+ 網站上仍然安裝的地方。攻擊者使用基於 UNION 的注入來轉儲 wp_users 表,獲取管理員密碼雜湊,並在離線破解弱密碼。
-- 日誌中典型 WordPress SQL 注入的樣子
GET /wp-content/plugins/vulnerable-plugin/ajax.php?id=1%20UNION%20SELECT%201,user_login,user_pass,4,5%20FROM%20wp_users--
PHP 物件注入和遠端程式碼執行
WordPress 對 serialize() 和 unserialize() 的大量使用創造了 PHP 物件注入的機會。當外掛對使用者控制的資料進行反序列化時(許多都這樣做),攻擊者可以製作在反序列化過程中執行任意程式碼的負載。
2024 年,流行備份外掛(安裝在 500 萬+ 網站上)中的關鍵遠端程式碼執行漏洞允許未經身份驗證的攻擊者執行任意 PHP 程式碼。修復花了 11 天才運送。11 天內,每個執行該外掛的網站都是靶子。
外掛供應鏈攻擊
這是最讓我害怕的。攻擊者購買具有大型安裝基數的放棄外掛,推送包含後門的「安全更新」,WordPress 自動更新機制將惡意軟體分發給執行該外掛的每個網站。它發生在 Display Widgets(300,000 次安裝)和 Social Warfare(70,000 次安裝)上,而那些只是被發現的。
對 wp-login.php 的暴力攻擊
每個 WordPress 網站預設公開 /wp-login.php 和 /xmlrpc.php。自動化殭屍網路不斷攻擊這些端點。Wordfence 報告在 2024 年平均在其網路中阻止了每月 30 億個惡意請求。即使使用速率限制和雙因素身份驗證,你也在花費伺服器資源處理這些攻擊。
通過主題和外掛的跨站指令碼 (XSS)
WordPress 中的儲存型 XSS 特別危險,因為管理儀表板和公開網站共享相同的會話上下文。通過註釋、表單提交或易受攻擊的外掛設定注入的 XSS 負載可以升級為完全管理員訪問。
為什麼無頭架構消除了整個攻擊類別
這就是事情變得有趣的地方。無頭架構不僅減少了你的攻擊面 -- 它通過移除使它們可能的條件消除了整個攻擊類別。
在傳統 WordPress 設定中,呈現 HTML 的同一伺服器也:
- 執行來自 20+ 第三方外掛的 PHP 程式碼
- 管理使用者身份驗證
- 連接到資料庫
- 提供管理介面
- 處理檔案上傳
- 處理表單提交
那是單一應用程式的很多責任。在具有 Next.js 和 Supabase 的無頭設定中,這些責任分佈在隔離的服務中:
- 前端 (Next.js on Vercel/Netlify): 從 CDN 提供的靜態 HTML/JS。在大多數情況下,沒有伺服器端執行時公開到公開網際網路。
- 資料庫 + 身份驗證 (Supabase): 具有行級安全的託管 Postgres,從不直接公開給最終使用者。
- API 層: 具有明確、最小端點的無伺服器函數。
- CMS(如果需要): 無頭 CMS 在其自己的隔離基礎設施上執行。
沒有 PHP 可以注入。沒有具有寫入訪問權限的外掛目錄。管理員和公開網站之間沒有共享會話。沒有 wp-login.php 供僵屍網路攻擊。
你不需要 WAF 來保護不存在的攻擊面。

Next.js + Supabase:以安全為優先的堆疊
讓我們從安全角度具體討論為什麼這個特定組合效果很好。
Next.js:不執行程式碼的前端
當你用靜態生成 (SSG) 或增量靜態再生 (ISR) 建立 Next.js 網站時,部署的是 CDN 上的 HTML、CSS 和 JavaScript 檔案。沒有應用程式伺服器即時處理請求。你無法 SQL 注入 CDN。
對於動態功能,Next.js Server Actions 和 Route Handlers 作為無伺服器函數執行。每個函數都:
- 在其自己的執行上下文中隔離
- 無狀態(請求之間沒有共享記憶體)
- 短暫(冷啟動、執行、終止)
- 明確定義(沒有自動發現端點)
// Next.js Route Handler -- 明確、有類型、最小化
import { createClient } from '@/lib/supabase/server'
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
const ContactSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
message: z.string().min(10).max(5000),
})
export async function POST(request: NextRequest) {
const body = await request.json()
const parsed = ContactSchema.safeParse(body)
if (!parsed.success) {
return NextResponse.json({ error: 'Invalid input' }, { status: 400 })
}
const supabase = await createClient()
const { error } = await supabase
.from('contact_submissions')
.insert(parsed.data)
if (error) {
return NextResponse.json({ error: 'Submission failed' }, { status: 500 })
}
return NextResponse.json({ success: true })
}
將其與必須掛入 WordPress 的操作系統、包含自己的 AJAX 處理程序、管理自己的 nonce 驗證和建立自己的 SQL 查詢的 WordPress 聯絡表單外掛進行比較。Next.js 版本的移動部件較少,通過 Zod 進行驗證的輸入,以及通過 Supabase 客戶端的參數化查詢。
Supabase:具有行級安全的 Postgres
Supabase 為你提供了一個託管 PostgreSQL 資料庫,有一個殺手級安全功能:行級安全 (RLS)。你不是依賴你的應用程式碼來強制訪問控制(WordPress 模型),而是在資料庫級別定義安全策略。
-- 只有經過身份驗證的使用者可以讀取自己的資料
CREATE POLICY "Users can view own profile"
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
-- 公眾可以插入到 contact_submissions 但不能讀取
CREATE POLICY "Anyone can submit contact form"
ON contact_submissions
FOR INSERT
WITH CHECK (true);
CREATE POLICY "Only admins can read submissions"
ON contact_submissions
FOR SELECT
USING (auth.jwt() ->> 'role' = 'admin');
即使攻擊者找到了進行任意 Supabase 查詢的方法(在沒有 PHP 執行上下文的情況下已經更難),RLS 策略也會防止他們訪問他們不應該看到的資料。這是 WordPress 根本無法提供的深度防禦,因為它的權限系統是在 PHP 程式碼中實現的,而不是在資料庫層級。
Supabase 也用內建支援電子郵件/密碼、魔術連結、OAuth 提供者和多因素身份驗證來處理身份驗證。不需要外掛。你的伺服器上沒有第三方程式碼執行。
攻擊面比較:WordPress vs 無頭
讓我們並排放在一起。
| 攻擊向量 | WordPress | Next.js + Supabase |
|---|---|---|
| SQL 注入 | 高風險 -- 外掛建立原始查詢 | 接近零 -- 通過 Supabase 客戶端參數化查詢,RLS 作為備份 |
| PHP/遠端程式碼執行 | 高風險 -- 外掛執行伺服器端 PHP | 不適用 -- 沒有 PHP 執行時 |
| 外掛供應鏈 | 關鍵風險 -- 自動更新分發惡意軟體 | 不適用 -- 沒有外掛生態系 |
| 暴力破解(登入) | 總是暴露 (wp-login.php, xmlrpc.php) |
通過 Supabase Auth 或單獨儀表板的管理員訪問,不需要公開登入端點 |
| XSS(儲存型) | 高風險 -- 共享管理員/公開上下文 | 低風險 -- React 預設轉義輸出,管理員和公開是單獨的應用程式 |
| 檔案上傳利用 | 高風險 -- 上傳的 PHP 檔案可以執行 | 低風險 -- 上傳到物件儲存 (Supabase Storage/S3),從不作為程式碼執行 |
| 資料庫公開 | 如果伺服器被入侵,直接 MySQL 訪問 | 資料庫在 Supabase 的基礎設施後面,RLS 策略作為最後防守 |
| 原點上的 DDoS | 伺服器必須處理每個請求 | CDN 上的靜態資產,原點很少被擊中 |
| 已知路徑列舉 | wp-admin, wp-content, wp-includes 都可掃描 |
沒有可預測路徑,沒有暴露的管理路由 |
遷移攻略:WordPress 到 Next.js + Supabase
好吧,你被說服了(或你被駭客的網站說服了你)。以下是實際操作方法。我們在 Social Animal 已經執行過這次遷移足夠多次,以至於有一個可重複的流程。
階段 1:分類和內容審核(第 1 週)
在你接觸任何程式碼之前,你需要了解你實際上有什麼。
- 使用 WP-CLI 或 REST API 匯出所有 WordPress 內容。不要依賴 XML 匯出 -- 它們遺漏了中繼欄位和自訂文章類型。
- 列出所有外掛提供的功能。製作電子表格:外掛名稱、它的功能、你是否真的需要它,以及什麼取代它。
- 映射 URL 結構以進行 SEO 保留。每個現有 URL 都需要重新定向或在 Next.js 中匹配的路由。
- 識別動態功能 -- 表單、搜尋、使用者帳戶、電子商務 -- 需要 API 端點。
# 通過 REST API 匯出 WordPress 內容
curl -s "https://yoursite.com/wp-json/wp/v2/posts?per_page=100&page=1" | jq '.' > posts_page1.json
curl -s "https://yoursite.com/wp-json/wp/v2/pages?per_page=100" | jq '.' > pages.json
curl -s "https://yoursite.com/wp-json/wp/v2/media?per_page=100" | jq '.' > media.json
階段 2:Supabase 架構和資料遷移(第 2 週)
根據內容審核設計你的 Supabase 資料庫架構。不要只複製 WordPress 架構 -- 它充滿了中繼資料表和序列化資料 blob。
-- 乾淨的、有目的的架構
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
content TEXT,
excerpt TEXT,
featured_image TEXT,
status TEXT DEFAULT 'draft' CHECK (status IN ('draft', 'published', 'archived')),
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
author_id UUID REFERENCES auth.users(id)
);
-- 立即啟用 RLS
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Published posts are public"
ON posts FOR SELECT
USING (status = 'published');
CREATE POLICY "Authors can manage own posts"
ON posts FOR ALL
USING (auth.uid() = author_id);
編寫一個遷移指令碼(Node.js 或 Python),將 WordPress JSON 匯出轉換為你的新架構並將它們插入 Supabase。
階段 3:Next.js 建立(第 3-5 週)
建立你的 Next.js 前端。如果你在處理懂堆疊的團隊,這進行得很快。如果你需要幫助,我們的 Next.js 開發團隊已經執行過這次遷移足夠多次,對正確的模式有強烈意見。
關鍵架構決策:
- 內容頁面的靜態生成 -- 部落格文章、登陸頁面、關於頁面。這些變成 CDN 上的 HTML 檔案。
- 動態資料的伺服器元件 -- 使用快取在請求時從 Supabase 取得。
- 表單提交的路由處理程序 -- 聯絡表單、電子報註冊等。
- 重新定向的中間件 -- 處理所有你的舊 WordPress URL。
// next.config.ts -- 處理 WordPress URL 重新定向
const nextConfig = {
async redirects() {
return [
{
source: '/category/:slug',
destination: '/blog/category/:slug',
permanent: true,
},
{
source: '/:year(\\d{4})/:month(\\d{2})/:slug',
destination: '/blog/:slug',
permanent: true,
},
// wp-login.php -- 傳送機器人到 410
{
source: '/wp-login.php',
destination: '/gone',
permanent: true,
},
{
source: '/wp-admin/:path*',
destination: '/gone',
permanent: true,
},
]
},
}
階段 4:測試和 SEO 驗證(第 6 週)
- 針對新網站執行 Screaming Frog 來驗證每個舊 URL 要麼解析要麼重新定向。
- 驗證結構化資料 (JSON-LD) 出現在所有頁面上。
- 測試所有表單和動態功能。
- 執行 Lighthouse 和 Core Web Vitals 檢查 -- 你幾乎肯定會看到改進,因為你現在從 CDN 提供服務。
- 設定使用 Vercel Analytics 或你選擇的工具的監控。
階段 5:啟動和 DNS 轉移(第 6-7 週)
部署到 Vercel 或 Netlify,更新 DNS,並設定監控。保持舊 WordPress 實例離線但在 30 天內可訪問,以防你需要參考任何內容。
如果你的網站有顯著流量或電子商務功能,考慮 無頭 CMS 整合進行內容管理,並與我們談論 Astro 作為替代前端以用於內容豐富的網站,其中建置性能很重要。
遷移後安全加固
一旦你在新堆疊上,這是你的安全檢查清單:
- 在每個表上啟用 Supabase RLS。 沒有例外。如果表沒有策略,它要麼無法訪問(好的預設)要麼完全開放(不好)。
- 為所有機密使用環境變數。 Vercel 和 Netlify 都很好地處理這個。從不提交 API 金鑰。
- 設定 Supabase 資料庫備份。 時間點恢復在 Pro 計畫($25/月)上可用。
- 在你的 Next.js 中間件中配置內容安全策略標頭。
- 啟用 Vercel 的 DDoS 保護(包含在所有計畫中)。
- 設定正常運行時間監控 -- 我們使用 Better Uptime,但 Checkly 和 Vercel 的內建監控也能用。
- 每季度審核你的 Supabase RLS 策略。 使用 Supabase 的 SQL 編輯器以不同使用者上下文測試策略。
// middleware.ts -- 安全標頭
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const response = NextResponse.next()
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
response.headers.set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
)
response.headers.set(
'Permissions-Policy',
'camera=(), microphone=(), geolocation=()'
)
return response
}
WordPress 安全的真實成本 vs 遷移
讓我們談談錢,因為那是實際上推動決策的。
| 成本類別 | WordPress(年度) | Next.js + Supabase(年度) |
|---|---|---|
| 主機 | $300-1,200(託管 WP) | $0-240(Vercel Pro) |
| 安全外掛 (Wordfence/Sucuri) | $200-500 | $0(不需要) |
| SSL/CDN | $0-200 | $0(包含) |
| 惡意軟體清理(如果被駭客入侵) | 每次事件 $500-2,500 | 不適用 |
| 開發者在安全補丁上的時間 | $2,000-5,000 | $500-1,000 |
| 資料庫 (Supabase) | 包含在主機中 | $0-300(免費層到 Pro) |
| 總計 | $3,000-9,400 | $500-1,540 |
而那是在考慮停機成本、失去的客戶信任和如果客戶資料被入侵的潛在監管罰款之前。單一 GDPR 可報告的違規可能花費數万美元的法律和合規開支。
遷移本身通常花費 $10,000-40,000,取決於網站複雜性。對於大多數企業,那在 1-2 年內在減少的安全支出中回報 -- 你還獲得一個更快、更可維護的網站。查看我們的 價格頁面以取得遷移專案的具體資訊。
常見問題
WordPress 真的那麼不安全,還是這被誇大了? WordPress 核心維護得很好。問題是幾乎沒有人只執行核心。外掛生態系是 96% 漏洞生活的地方,你無法在沒有外掛的情況下執行有用的 WordPress 網站。沒有誇大 -- Sucuri 在 2024 年從 60,000 多個 WordPress 網站清理了惡意軟體。架構要求你信任你的伺服器上的第三方 PHP 程式碼,而且這信任一直被利用。
我不能只使用更好的安全外掛而不遷移? 安全外掛本身是在你的伺服器上具有深度系統訪問的 PHP 程式碼。Wordfence 和 Sucuri 維護得很好,但它們是架構問題的創可貼。它們也增加了伺服器負載,可能與其他外掛衝突,並且多年來有自己的漏洞。你在添加複雜性以解決複雜性問題。
WordPress 到 Next.js 遷移通常需要多長時間? 對於標準商業網站(10-50 頁、部落格、聯絡表單),我們通常在 5-7 週內完成遷移。具有 WooCommerce 的電子商務網站更複雜,可能需要 8-14 週,取決於產品目錄大小和自訂功能。如果你有更簡單的網站,聯繫我們,我們可以給你更具體的時間表。
遷移 WordPress 時,我會失去 SEO 排名嗎? 如果你做對了不會。關鍵步驟是:保留所有 URL 結構或設定適當的 301 重新定向、維護你的結構化資料標記、保留你的內容完好,並向 Google Search Console 提交更新的網站地圖。我們大多數遷移客戶在 2-3 個月內看到排名改進,因為當你遷移到 CDN 提供的靜態網站時,Core Web Vitals 分數戲劇性改進。
內容編輯怎麼樣?WordPress 對非技術使用者很容易。 這是一個合法的關注。你有選項:使用自訂管理儀表板的 Supabase,或無頭 CMS,如 Sanity、Contentful 或 Payload CMS,為內容編輯提供類似 WordPress 的視覺編輯經驗。我們定期處理 無頭 CMS 整合,可以推薦適合你團隊需求的正確選項。
Supabase 對生產使用足夠安全嗎? Supabase 在 AWS 基礎設施上執行,具有 SOC 2 Type II 合規。基礎資料庫是 PostgreSQL,具有強大的安全記錄。行級安全策略在資料庫級別強制訪問控制,實際上比 WordPress 的基於 PHP 的權限系統更安全。Supabase 也提供時間點恢復、加密連接以及付費計畫上的網路限制。
如果我的 WordPress 網站被駭客入侵,我需要立即幫助怎麼辦? 首先,立即離線網站以停止進一步損害和資料洩露。其次,保留取證證據(資料庫轉儲、訪問日誌、檔案系統快照)。第三,不要只清理它並放回去 -- 你可能會在幾週內被重新感染。使用該事件作為遷移的催化劑。聯繫我們的團隊,我們可以幫助進行即時分類和遷移規劃。
我是否需要一次遷移所有內容,或者可以逐步執行? 增量遷移是可能的,但增加了複雜性。你可以執行 Next.js 作為前端,同時暫時保持 WordPress 作為無頭 CMS 後端,然後完全淘汰 WordPress。然而,這意味著 WordPress 仍在執行,在過渡期間仍然需要安全維護。對於大多數網站,乾淨的轉移速度更快、更便宜,並更快消除安全風險。