max_input_vars錯誤導致資料傳輸異常

max_input_vars錯誤導致資料傳輸異常

max_input_vars 錯誤導致資料傳輸異常

Input variables exceeded 1000的錯誤是因為在php.inimax_input_vars預設值為1000,當數量超過1000php會拋出E_WARNINGE_WARNING的錯誤訊息並不會造成中斷(halted),但是會導致數據在傳輸超過1000之外的變數為null,所以可能會間接的導致系統異常。

近期客人在新增訂單時,發現該筆訂單有些內容正常,但是有部分內容異常。查了程式碼半天發現都沒有問題,最後打開瀏覽器看response時才發現有錯誤訊息

Warning:  Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0<br />

再細查才發現,這一個POST包含了超過1000個變數,所以第1001個變數外的內容都被設定為null,又很剛好的1001個變數之後的每個變數都沒有關連/null時並不會引起系統錯誤…

經上網查詢後才發現這是由php.iniRuntime Configurationmax_input_vars控制。可以透過指令列查詢數值

php -ini|grep max_input_vars

解決方法

筆者目前使用到的解決方法有二:一個是直接修改php.ini的檔案即可,另一個是針對該網頁應用程式( web application)的.htaccess做修改

備註:由於max_input_vars本身的ChangeablePHP_INI_PERDIR,所以無法透過ini_set()的方式修改,可參考

1. 方法一:直接修改php.ini

理論上來說,找到php.ini 找到該數值之後更新,並重啟apache就可以了。

php --ini // 確定php.ini location
cd /PATH/TO/PHP.INI
sudo vim php.ini // 找到max_input_vars,並把[;]取消,將數值改為2000
sudo apachectl restart

直接修改php.ini是修改設定檔,會間接的導致同台主機上的其他服務都會受到影響。如果只想針對單一web application 的內容做修正的話,可以採用第二種方式:針對.htaccess做修改

2. 方法二:修改.htaccess

laravel的框架來說,在每個public資料夾內都會有.htaccess的檔案,用來管控整個應用程式的讀取權限。

.htaccess內加上

php_value max_input_vars 2000 //輸入你要的數字

即可直接完成設定,且不需要重啟apache

結語

最後我們來看一下php上的說明:max_input_vars

How many input variables may be accepted (limit is applied to $_GET $_POST and $_COOKIE superglobal separately). Use of this directive mitigates the possibility of denial of service attacks which use hash collisions. If there are more input variables than specified by this directive, an E_WARNING is issued, and further input variables are truncated from the request.

手冊上寫明了Use of this directive mitigates the possibility of denial of service attacks which use hash collisions,可以減少DDOS的發生可能,所以站在資安的角度來說,我們不應該去改變這個數值,應該要嘗試去改變POST的變數數量,例如可能把重複性高的變數放成json處理後再傳送。