這個來自一些項目中,獲取用戶Ip,進行用戶操作行為的記錄,是常見並且經常使用的。 一般朋友,都會看到如下通用獲取IP地址方法。
1 public static function getIp() 2 { 3 if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]) 4 { 5 $ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]; 6 } 7 elseif ($HTTP_SERVER_VARS["HTTP_CLIENT_IP"]) 8 { 9 $ip = $HTTP_SERVER_VARS["HTTP_CLIENT_IP"]; 10 } 11 elseif ($HTTP_SERVER_VARS["REMOTE_ADDR"]) 12 { 13 $ip = $HTTP_SERVER_VARS["REMOTE_ADDR"]; 14 } 15 elseif (getenv("HTTP_X_FORWARDED_FOR")) 16 { 17 $ip = getenv("HTTP_X_FORWARDED_FOR"); 18 } 19 elseif (getenv("HTTP_CLIENT_IP")) 20 { 21 $ip = getenv("HTTP_CLIENT_IP"); 22 } 23 elseif (getenv("REMOTE_ADDR")) 24 { 25 $ip = getenv("REMOTE_ADDR"); 26 } 27 else 28 { 29 $ip = "Unknown"; 30 } 31 if(strpos($ip, ',') !== false){ 32 $ip = explode(',', $ip); 33 $ip = reset($ip); 34 } 35 return $ip; 36 } 37
-
IP獲取來源
1.’REMOTE_ADDR’ 是遠端IP,默認來自tcp 連接是,客戶端的Ip。可以說,它最准確,確定是,只會得到直接連服務器客戶端IP。如果對方通過代理服務器上網,就發現。獲取到的是代理服務器IP了。
如:a->b(proxy)->c ,如果c 通過’REMOTE_ADDR’ ,只能獲取到b的IP,獲取不到a的IP了。
另外:該IP想篡改將很難實現,在傳遞知道生成php server值,都是直接生成的。
2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 為了能在大型網絡中,獲取到最原始用戶IP,或者代理IP地址。對HTTp協議進行擴展。定義了實體頭。
-
結論:
上面getip函數,除了客戶端可以任意偽造IP,並且可以傳入任意格式IP。 這樣結果會帶來2大問題,其一,如果你設置某個頁面,做IP限制。 對方可以容易修改IP不斷請求該頁面。 其二,這類數據你如果直接使用,將帶來SQL注冊,跨站攻擊等漏洞。至於其一,可以在業務上面做限制,最好不采用IP限制。 對於其二,這類可以帶來巨大網絡風險。我們必須加以糾正。
需要對getip 進行修改,得到安全的getip函數。
這類問題,其實很容易出現,以前我就利用這個騙取了大量偽裝投票。有它的隱蔽性,其實只要我們搞清楚了,某些值來龍去脈的話。理解了它的原理,修復該類bug將是非常容易。
題外話,做技術,有三步,先要會做,會解決;后要思考為什么要這么做,原因原理是什么;最后是怎么樣做,有沒有其它方法。多問問自己,你發現距離技術真理越來越近。你做事會越來越得心應手的!