WordPress Nonce 是什麼以及如何使用

Nonce 是 WordPress 安全的一個重要組成部分,但是 Nonce 經常會被誤解以及誤用。它們是授權一個 HTTP 請求到您的網站的一個關鍵部分,用來保證你的代碼安全。

在這篇文章中,您將了解什麼是 nonce,一個 WordPress nonce 是什麼,它們是如何能夠防禦某些類型的攻擊,還有他們無法防禦的攻擊類型,以及如何使用它們。

什麼是 WordPress Nonce

Nonce 是加密散列,用來驗證是否是正確的人或客戶端所發送的請求。因為 nonce 是使用一個加密散列演算法(例如 md5,sha1,sha2)和某種形式的秘密數據構造的,一般來說不太可能創建一個假的 nonce。

nonce 這個單詞意思是:僅使用一次的數字。nonce 安全性的一個關鍵特性就是一次性使用。即使你攔截獲得了一個有效的 nonce,一旦它被使用了,就無法再次使用。這個使得 nonce 對於重複攻擊很有效。

就是說,WordPress nonce,並不是真正的 nonce,因為它可以在某段時間內一直有效,可以通過 nonce_life(詳見Code Reference) 這個 filter 來定義它從創建開始的時效。這個意味著從技術上講 WordPress nonce 可以使用不止一次,但僅限這個定義的時間段里。這個是需要謹記在心的區別。

跨站點請求偽造

我們經常認為我們的 WordPress 站點僅僅通過填寫表單(如結賬表單,文章編輯器,用戶個人資料編輯器等等),然後點擊提交來接受數據。但是那個僅僅是向一個站點發送 HTTP 請求的許多方法中的一個。

一旦一個表單的結構被摸清,然後就可以寫一個腳本來模仿向這個表單發送請求。利用此漏洞來進行攻擊的一種方式就是:在另外一個站點放上此表單的假版本,然後提交回原站點,來插入惡意數據。

這個就是一個跨站點請求偽造(CSRF)的攻擊例子。它很大程度上可以通過使用 nonce 來避免。即使表單保持一模一樣,然而 nonce 欄位的值無法猜到。

每個發送給 WordPress 站點的請求,一個選項表單,一個針對 admin-ajax 的請求,Wordpress REST API,或者其他任何可以在站外發起的請求,都應該通過 nonce 來保護。

Nonce 只是整個系統的一部分

需要記住的是:僅驗證一個 nonce,對於確定發送的請求是否經過授權是不夠的。對於任何一個請求,許可權的檢驗都是必要的。思考下面3個在 WordPress 插件中使用 admin-ajax 保存選項的例子:

<?phpadd_action( wp_ajax_save_weibo, function(){ if( isset( $_POST[ weibo ] ) ){ update_option( weibo, strip_tags( $_POST[ weibo ] ) ); }}); add_action( wp_ajax_save_weibo, function(){ if( current_user_can( mange_options ) && isset( $_POST[ weibo ] ) ){ update_option( weibo, strip_tags( $_POST[ weibo ] ) ); }}); add_action( wp_ajax_save_weibo, function(){ if( current_user_can( mange_options ) && isset( $_POST[ weibo-save-nonce ], $_POST[ weibo ] ) && wp_verify_nonce( $_POST[ weibo-save-nonce ], weibo-save-nonce ) ){ update_option( weibo, strip_tags( $_POST[ weibo ] ) ); }});?>

第一個例子允許任何擁有有效 cookie 的任何角色的用戶來更新這個選項。如果你在 WordPress 站點使用這個代碼,而我註冊為一個訂閱者,我可以登錄到這個網站,獲得我的 cookie,然後就可以使用瀏覽器控制台或者在我的 terminal 中使用 cURL 來修改這個選項。這是非常不安全的做法。

第二個例子會好一些,但是仍然不安全。這個代碼中沒有 nonce,但是它正確的檢查了當前用戶的許可權。沒有 nonce,正如我們前面講的會受到跨站點請求偽造的攻擊影響。這段代碼就是釣魚攻擊網站的邀請函啊。

第三個例子增加了一個 nonce,這是正確的做法。如果我有個管理員 cookie 設置,同時我輕易被釣魚網站欺騙了,這時候 nonce 將會起作用,讓它通過不了,也就不會造成任何破壞。

Nonce 配合著身份驗證一起工作,這樣就無法跳過這一個或者另一個驗證了。

使用 Nonce

WordPress 有著一系列的函數來和 nonce 配合工作。其中兩個最重要的函數是 wp_create_nonce() 和 wp_verify_nonce。都可以為動作執行(action)傳入可選參數。你應當始終為你的請求設置唯一的動作執行(action)。這意味著你的 nonce 不可以用來重複驗證另外一種類型的請求。

對於 nonce 在表單中使用,有一個助手函數(helper function)叫 wp_nonce_field(),可以用來創建一個 nonce 隱藏欄位。下面這個表單可以和上面例子配合:

<form id="weibo-form"> <label for="weibo-name"> <?php esc_html_e( Weibo, text-domain ); ?> </label> <input type="text" id="weibo-name" value="<?php echo esc_attr( get_option( weibo, ) ); ?>" /> <?php wp_nonce_field( weibo-save-nonce ); submit_button( __( Save, text-domain ) ); ?></form><script> jQuery( document ).ready(function($){ $( #weibo-form ).on( click, function(e){ $.post( ajaxurl, { weibo-save-nonce : $( #_wpnonce ).val(), weibo: $( #weibo-name) }) }); });</script>

這個將會用在只有管理員可以看到的菜單頁面。因此 nonce 在被使用輸出到屏幕顯示的時候,只有管理員可以看到。在 admin-ajax 的回調函數中,nonce 驗證和許可權驗證,結合 WordPress 對用戶 cookie 的驗證,一起來保證安全。

在這個例子中,我們使用了 AJAX 來提交表單,但是對於同步 HTTP 請求,這個過程是一樣的。

現在就開始使用 Nonce

這就是關於 nonce 的一切了。為了提高 WordPress 網站的安全性,記住,無論如何都要使用 Nonce。

在我總結之前,還有另外兩個觀點需要說的是:

關於 Nonce 有一個重要的事情需要謹記在心的是,nonce 其中的一個組成部分就是當前用戶的 ID,如果沒有登錄就是 0。這個意味著 nonce 在用戶之間不可分享。這個可能會讓人產生困惑,就是如果 nonce 在用戶身份驗證之前驗證,那麼正確的 nonce 將會無效。當一個 nonce 伴隨著 WordPress REST API nonce 用來驗證 cookie 身份驗證被使用時,這就是一個會發生的問題。

另外一個重要的事情需要記住的是,nonce 會受到 PHP 計時攻擊的影響。這就是為什麼 WordPress 用戶需要故意使用低效率的函數 hash_equals() 替代簡單高效的字元串比較。你可能產生過通過生成一個期望的值然後用字元串比較來驗證一個 nonce 的念頭。然而,我建議你不要嘗試和優化 nonce 驗證的過程。

就這麼多,僅僅簡單地介紹了如何使用 nonce。我希望通過這篇文章你可以看到 nonce 是多麼的簡單,以及對於保證你的代碼和站點安全是多麼的重要。

原文鏈接:Wordpress Nonce 是什麼以及如何使用


推薦閱讀:

Kali Linux VMware安裝版小白級教程
WordPress 4.7.1命令執行代碼Sql注入漏洞
諮詢對我而言,早已不是一個職位那麼簡單
古代是怎麼通緝人員的?
網路安全 | kali linux系統

TAG:網路安全 | WordPress |