WordPress 接案者一定要懂的 CSRF 與權限檢查


如果你有在使用 AI 開發 WordPress 外掛,並且要設計一些自訂的後台管理介面時,一定遇過資料送出時無法正確儲存,或是儲存後被導向到奇怪的頁面。

根據我的經驗,這十之八九是 Nonce 的問題,AI 在處理 Nonce 這一塊常常會出錯,為了讓 AI 更好地理解該怎麼處理 Nonce,這篇文章就來分享 Nonce 的作用,以及如何讓 AI 不要再犯這種錯。

Nonce 是為了擋 CSRF 而生的

所謂的 Nonce,最主要的功能是要防止跨站請求偽造(也就是俗稱的 CSRF)。

CSRF 主要的攻擊方式,是攻擊者誘導已經登入受害者的瀏覽器,自動發送請求到你的網站,也就是說,攻擊者不需要入侵你的網站,只要你的瀏覽器在登入狀態下點擊了惡意網址,攻擊就會開始。

舉個例子:

  1. 站長登入了某個 WordPress 網站的後台沒登出,繼續開著分頁
  2. 站長切換到另一個由惡意攻擊者準備好的頁面,這個惡意頁面藏了一段惡意程式
  3. 程式裡面的連結會指向站長 WordPress 後台
  4. 瀏覽器在送出這個請求時,會自動帶上站長已經登入的 Cookie(因為原本分頁沒關)
  5. 站長踩到這個惡意網址、讀到那段 HTML 裡埋的 JavaScript 與 WordPress 後台執行參數,網站就會受到影響

另一種方式,是用 JavaScript 自動提交表單來攻擊。只要你的分頁沒關、進入惡意網址,而惡意網址又知道你的後台位置,它就能進行跨站請求偽造,達成攻擊,而 WordPress 的後台網址你知、我知、獨眼龍也知,因此非常容易用釣魚的手法誘使受害者點擊。

Nonce 怎麼擋住 CSRF

為了解決這個問題,WordPress 設計了 Nonce 機制,用來確保每一個請求都是從自己的網站送出的。Nonce 的全名是 Number Used Once,也就是只用一次的數字,但這個名字其實有點誤導,因為它預設的有效期限是 12 到 24 個小時。

它的運作原理適當使用者載入網站的某個介面(後台、設定頁、表單頁)時,伺服器會用 wp_create_nonce() 產生一段 Token,這段 Token 會被放進後台介面的隱藏欄位,或塞進 JS 的變數裡。

當使用者按下按鈕觸發操作時,前端會把這個 Nonce 跟其他資料一起送回伺服器。伺服器收到後,用 wp_verify_nonce() 比對 Nonce 是否相符。如果通過,就代表這個請求是從我自己的網站介面送出的。

它能擋住 CSRF 是因為計算 Nonce 的時候帶了 Secret Key(存在 wp-config.php 裡的加密金鑰),這個金鑰只有你自己的網站知道,惡意網址沒辦法產生出能通過驗證的 Nonce,攻擊者無法取得正確的 Nonce 來偽造請求,CSRF 就能擋下來了。

但光有 Nonce 還不夠

WordPress 的前台與後台雖然都有 Nonce,但光靠 Nonce 其實是不夠的。

關鍵點在假設今天攻擊者註冊成為你的網站會員(例如訂閱者),當他登入後打開外掛的某個前台頁面,伺服器就會為他產生一個合法的 Nonce,這時他拿到這個 Nonce,就可以放到自己準備的請求中,藉此發送一個「合法的」跨站偽造請求。

所以,除了 Nonce 之外,我們還要檢查身分權限,確保目前的使用者真的有權限執行當下的行為。

基本原則是:如果要防止 CSRF,同時也防止低權限使用者拿到 Nonce 來偷襲,記得除了驗證 Nonce 之外,還必須檢查使用者權限,尤其是當後台操作會修改資料庫,或查詢敏感機密資料時,都要做到 Nonce 與使用者權限的雙重檢查

一張票進 VIP 廳?想像電影院的剪票口

換個方式理解這件事——想像你去看電影:

  1. 你在訂票網站訂了「賭俠 19:30,第 5 排第 3 座」,拿到一張票
  2. 進電影院門口,剪票員看你的票,確認「你有資格進賭俠 19:30 那個放映廳」,這就是 Nonce 驗證:「你帶對票了嗎?」
  3. 但剪票員不會檢查你是 VIP 還是學生,身分是另一回事

回到 WordPress:

電影院WordPress 對應API防什麼票noncewp_create_nonce() / wp_verify_nonce() / check_ajax_referer()CSRF:證明請求來自合法介面身分驗證capabilitycurrent_user_can( 'capability' )權限提升:證明操作者有對應角色

兩道防線缺一不可:

  • check_ajax_referer() 確認「這張票是我們電影院的票」——擋外部誘導攻擊
  • current_user_can() 確認「拿票的人有 VIP 廳的資格」——擋內部低權限帳號偷襲

AI 寫 Nonce 最常犯的錯:名稱對不上

一個 AI 常犯的問題是它在埋入表單頁面的 Nonce 名稱,跟後端驗證時用的名稱常常不一致,一個頁面中可能同時有多個表單操作行為,AI 很容易搞混特定的 Nonce 應該用在哪一個動作上。

比較好的做法是:

  1. 請 AI 先規劃每一個表單的 Nonce 該用什麼名稱
  2. 請 AI 把這些名稱整理成表格
  3. 讓 AI 在進行資料操作與驗證時,對照表格使用正確的 Nonce,避免名稱錯亂

簡單舉例,可以請 AI 先列出像這樣的對照表再開始寫程式碼:

表單行為Nonce action 名稱Nonce 欄位名驗證點儲存設定dwp_save_settingsdwp_settings_nonceadmin_post_dwp_save_settings刪除文章dwp_delete_postdwp_delete_noncewp_ajax_dwp_delete_post匯入 CSVdwp_import_csvdwp_import_nonceadmin_post_dwp_import_csv

把這張表給 AI 當「規格」,再讓它寫程式碼就能大幅降低 Nonce 名稱錯亂的機率。

接案者的自我檢查清單

接到的案子要稽核安全,或自己用 AI 寫的時候要避雷,可以照這個清單檢查每一個 wp_ajax_* 或表單 hook:

  1. 這個動作會改資料庫嗎?(刪除、修改、新增)會的話必檢查下面三項
  2. check_ajax_referer()wp_verify_nonce() 嗎? 沒有,CSRF 就沒擋
  3. current_user_can( '某個合理的 capability' ) 嗎? 沒有,訂閱者就能偷襲
  4. 輸入有 intval() / sanitize_text_field() 等過濾嗎? 沒有就是 SQL injection 或 XSS 的入口

四個都做到,才算「我加了 nonce 啊」這句話真的成立。

如果想看完整的 WordPress 外掛安全稽核流程,可以接著看逆向走一次 WordPress 外掛漏洞,學會資安稽核的攻擊者思維;如果是 XSS 那一塊還沒讀過,WordPress XSS 攻擊:漏洞成因與真實 CVE 攻擊案例會把另一條漏洞線補上。整站層級的弱密碼、檔案竄改、XML-RPC 防護則整理在WordPress 安全防護實戰這篇。

用 AI 寫 WordPress 外掛踩到坑想找人聊聊?

如果你正在用 AI 開發 WordPress 外掛或客製化網站,但每次遇到 Nonce、權限、漏洞這類安全問題就卡住,或者寫出來的程式碼自己也不確定有沒有藏雷——歡迎來聊聊。

我提供兩種服務:

  • WordPress 客製化開發:直接把案子交給我做,從架構規劃到安全稽核一條龍,適合手上有客戶但人力不足的工作室,或是專案技術門檻高、不想自己踩坑的接案者。
  • WordPress AI 開發顧問諮詢:把我累積 11 年的 WordPress 開發經驗變成你的方法論,涵蓋流程盤點、客製化框架、漏洞情報監控,適合想導入 AI 但不知道怎麼控品質的接案團隊。

不取代你開發,而是讓你的 AI 開發流程不會踩到因為 Nonce 而造成的卡關。

歡迎到 WordPress AI 開發顧問服務 看完整方案,或與我聯絡聊聊你的案子。

WordPress 開發日常

Read more from WordPress 開發日常

昨天下午跑去臺北中山地下街想說放空一下抽離每天的日常工作,結果逛書店逛到一半,旁邊走過的兩個人開始在高談闊論,聊著關於 AI 上下文超過 50% 能力表現就會開始衰退的話題,害我都很想過去跟著討論一番XD Typeless 不只是語音輸入工具,更是 AI 助理 語音輸入軟體 Typeless 的方便性應該不用我再多說了,有很多朋友應該都有在用,但最近我發現了幾個進階的用法,能夠再進一步提升我的 AI coding 效率甚至是平常的文書作業。首先是「隨便問」這個功能,Mac 上預設的快速鍵是 Fn + Space,我發現它有以下用法: 一、潤飾文字稿 當我語音輸入完、想要把輸入好的內容再重新順一下時,我可以直接把剛剛輸入的文字選取起來,然後使用 Fn + Space 跟它說:「請幫我潤飾一下這段文字,並且幫我把原始文字括號,讓我知道你修改了哪些地方。」 二、深度分析與摘要 當你面對冗長的文件、複雜的報告或大量的資訊時,不必逐字閱讀。只需將內容選取後呼叫「隨便問」,它便能迅速為你梳理出核心論點、關鍵數據及邏輯架構,並將繁瑣的資訊轉化為簡潔易懂的重點摘要。 三、網頁搜尋...

最近在讀一本書叫做《Vibe Coding 聖經》,在現在 AI 相關的書籍多到爆炸的狀況下,很容易就覺得這只是另外一本在教人用 AI 寫 Code 的過時書籍而略過,但讓我眼睛一亮的是本書的其中一位共同作者 Gene Kim 是我超愛的一本軟體專案管理小說神作《鳳凰專案》的作者,他與另一位骨灰級工程師合著,因此二話不說就立刻買回來看。 這本書是 2025 年中出版的。在那個時間點,Vibe Coding 的說法剛出來不久,所以第一章的篇幅著墨在說服還沒有嘗試過 Vibe Coding 的工程師來實際體驗看看,書中舉了很多矽谷創業圈的例子來佐證,證明 Vibe Coding 是真的會改變軟體設計的一種典範轉移。 Kim 也提到有很多早就因為寫不下去程式碼而離開這個產業的工程師,因為這一波 Vibe Coding 的浪潮又重新找回軟體開發的樂趣,其中就包含他自己。他的本業是協助企業來如何透過 IT 來管理企業,而《鳳凰專案》這本書在講的就是這個的主題。 《Vibe Coding 聖經》提到 AI 協作開發把工程師最討厭的瑣事像是除錯、寫測試、部署流程全部都外包給...

上一次也是第一次參加鐵人賽是 2021 年,因為受到社群夥伴 Eric 的邀約,我寫了關於接案以及 WooCommerce 金流串接的主題,雖然只有得到全勤獎且壓力爆棚,但還是靠著意志力完成這個累死人不償命的比賽。 IT 鐵人賽是由台灣最大的技術開發社群 IT邦每年都會舉辦的線上活動,邀請所有技術產業的從業人員把他們的研究心得或是實作經驗以連續三十天的頻率發表出來,挑戰前可以選擇要投稿的題目,剩下的就是在半夜 12 點前準時發文,如果遲了一分鐘挑戰就算失敗。 當年參賽挑了一個我很害怕的主題:WooCommerce 金流串接,這是我自學程式的大魔王關卡,很大一部分是因爲當年閱讀技術文件非常吃力,然後 WooCommerce 的 API 又有很多看不懂的寫法,我想用鐵人賽來克服心魔。 這是我當年參賽後的心得:「參賽前我一直很擔心自己沒有辦法寫完這三十天,不停的在懷疑自己是否有辦法辦到,但就跟做很多一開始覺得很困難的案子一樣,頭洗下去之後就會慢慢看得到終點了,今天的我感覺自己突破了很大的一關!」...