PHP基礎:關於 php.ini 中 max_input_vars 的設定


Overview

由於我們在做的 LLMOps產品中經常需要讓用戶上傳含有很大量紀錄筆數的 CSV檔案,如果只有上傳檔案並在後端進行處理其實不會遇到這樣的問題,但我們的功能需求是要讓使用者上傳完 CSV後先從 CSV中解出資料並讓用戶在 Web UI上進行檢視與校正,所以我們有位同仁在設計這功能時沒有考量到 php.ini 中有 max_input_vars 預設值為 1000的這項限制並將送出的 POST payload設計成很容易超出這個預設值的方式,雖然有經驗的同仁會在前端送出時將所有數據直接轉換成一整包大 JSON做 POST payload發送到後端,我也認為這樣做會安全很多,畢竟調高 max_input_vars 還是有其 trade-off 風險在,不過這邊還是做些筆記,讓想要在 php.ini 中決定最佳的 max_input_vars 設定值的朋友們可以有個系統化的方式來決定是否要調整這個值以及要設定為多少的數量。

理解 max_input_vars

  • max_input_vars 這個參數限制了通過 $_POST$_GET$_COOKIE 傳遞的變數數量。預設值為 1000
  • 它的主要目的是防止 阻斷式服務攻擊(DoS),避免攻擊者透過發送過多的輸入變數導致伺服器資源耗盡或顯著降低效能。

確定應用程式的需求

  • 表單的複雜度:如果你的應用程式使用了大表單,尤其是包含陣列的表單(例如複雜的電商系統或多步驟表單),你可能需要提高這個限制。
  • 輸入字段數量較多的頁面:如果你的 POST payload 帶有很高的參數數量(例如一個龐大的產品目錄或資料匯入工具),就需要較高的設定值。
  • API 或批次操作:如果應用程式處理大量資料上傳或與需要發送大量資料的 API 整合,可能也需要提高這個參數值。

測試:檢查當前使用情況

確定當前設定是否足夠?

  • 如果你看到錯誤訊息,例如 Warning: Input variables exceeded x,這表明 max_input_vars 設定值對應用程式來說太低了。
  • 如果在提交含有大量變數的表單時,$_POST 陣列是空的,這可能意味著 max_input_vars 設定不足。

平衡安全性與功能

  • 過低的設定值:如果設置得太低,當用戶提交含有大量變數的表單時,應用程式可能會出現問題。
  • 過高的設定值:如果設置得過高,可能會使應用程式更容易受到攻擊,惡意用戶可能會試圖傳送過量變數,導致伺服器資源耗盡。
  • Best practice:將 max_input_vars 設定為足夠應用程式正常運行的最小值。對於大多數簡單的網頁應用程式,1000-2000 通常已經足夠,至於複雜應用可能需要 5000 或更高,但應先進行測試。

資源考量

每個輸入變數都會消耗記憶體,處理的變數越多,記憶體使用量就越高,如果伺服器的相關資源有限,增加 max_input_vars 過多可能會導致記憶體耗盡或效能問題。

  • 在增加這個值時,監控記憶體使用情況。
  • 確保 php.ini 中的 memory_limit 設定適合處理較大的表單 POST payload。

修改 php.ini 中的 max_input_vars

打開 php.ini 文件

bash sudo nano /etc/php/7.x/apache2/php.ini 
# 對於 Apache 

sudo nano /etc/php/7.x/fpm/php.ini
# 對於 PHP-FPM

找到 max_input_vars 這個參數(如果沒有可以新增):ini max_input_vars = 3000;根據應用程式需求設置這個值(例如 2000、3000 或 5000)。

重啟 Apache去套用 php.ini 內的變更

bash sudo systemctl restart apache2 
# 對於 Apache 

sudo systemctl restart php7.x-fpm 
# 對於 PHP-FPM

更改後的監控

  • 監控 error log(如 /var/log/apache2/error.log/var/log/php-fpm/error.log),檢查是否有任何問題。
  • 測試應用程式中最大 POST payload,確保 payload 能夠正確送出且沒有錯誤。
  • 如果仍然出現「輸入變數超過限制」的錯誤,可能需要進一步提高值,或者研究其他方式來更有效地處理大型 POST payload。

其他相關設定

當增加 max_input_vars 時,可能還需要檢查並調整以下參數:

  • post_max_size:PHP 接受的 POST payload 的最大數值。
  • memory_limit:確保 PHP 有足夠的記憶體來處理更大的 POST payload。

php.ini 設定值範例

max_input_vars = 3000
post_max_size = 32M
memory_limit = 128M

小結:選擇 max_input_vars 的最佳值

  • 從預設的 1000 開始。
  • 根據應用程式需要發送到後端的參數數量逐步增加這個值。
  • 對於大多數應用程式,範圍為 2000-5000,但應該盡可能保持較低值,以確保安全性並防止潛在的 DDoS。

透過這樣的結構化方式,你可以找到最適合應用程式需求的 max_input_vars 設定,同時保持效能和安全性。

Leave a Comment

Your email address will not be published. Required fields are marked *