跳轉到

PHP取得使用者IP所引發的...坑

起因

我有一個長年在日本發展的朋友,他和他妻子昨天回台灣度假。他們夫妻倆約我今日下班小聚。

我朋友是後端工程師,他的妻子是前端工程師。他們倆是屬於那種「會後端就不會前端,會前端就不會後端」的極端類型。但也正因如此,我一直覺得他們在自己各自專精的領域十分專業,畢竟他們不像我一樣學的東西很雜。

他們夫妻倆在日本開了一間小公司,性質類似於專門接案的工作室。據他們說,公司員工不多,包含他們夫妻倆再加上三個日本人,也就五位而已。

我曾問他們,既然都是在做接案性質的工作,為什麼不在台灣做?他們說在日本雖然辛苦,但是自由。只不過,雖然有這令人嚮往的自由,但有時候面對奧客真的挺煩人的。

我雖然不太清楚在日本接案跟在國內接案的差異,但就以我自己本身的接案經歷,總覺得奧客這個問題,應該不管在哪個國家都會有。當然,因為每個人都有不同感受,我也沒有繼續在這個問題上深入進去。

我和他們在一間熱炒店一邊喝著小酒,一邊聽他們夫妻倆抱怨著他們所接觸客戶的事情。他們抱怨著在上個月接的案子裡,有一個客戶一直對他們開發的系統上某個功能所引發的 Bug 有點不滿意。

我心中感到疑惑。以我對我朋友的了解,即使有 Bug,他也不會將問題擺著不放,因為這不像他的個性。我好奇地問他,到底是什麼問題讓他那麼苦惱?

取得使用者IP

他拿起手機,連上GitHub網站,向我展示了一段程式碼:

$ip = $_SERVER['REMOTE_ADDR'];
我有點疑惑,這段程式碼怎麼了?這就是很單純的取得使用者IP的程式碼片段而已,我問他,這段程式碼有什麼問題嗎?他告訴我說,這段程式碼是用在寫Log時記錄使用者IP時用的。

我有點不太確定的說,該不會他們認為IP不準確吧?他點了點頭露出苦笑,我依舊疑惑,感覺這個不是什麼小問題啊,因為大部分寫了一陣子的PHP工程師都知道$_SERVER['REMOTE_ADDR']可能會因為使用者使用Proxy或VPN,抓到的IP是不準確的阿,所以都是將Header都記錄到Log內,之後有什麼問題需要確認IP,再去透過紀錄的Header查使用者的HTTP_CLIENT_IPHTTP_X_FORWARDED_FORREMOTE_ADDR,最後再用人工肉眼比對,這個應該是最後的解法吧,雖然我不太清楚這個為什麼是問題點,我想只要跟客戶說明清楚就好了。

他點了點頭對我說,他當初也那麼想,而且那個功能上其實有額外紀錄,HTTP_CLIENT_IPHTTP_X_FORWARDED_FORREMOTE_ADDR,只不過那套說詞對方無法接受,而且業主的工程師給他一段程式碼,認為取IP應該要這樣,然後他還被嘲諷一番…

接著他又讓我看了看業主的工程師貼的程式碼。

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}
我看這段程式碼,對他說,他們的工程師不知道HTTP_CLIENT_IPHTTP_X_FORWARDED_FOR是可以偽造的嗎?即使真的沒有人透過特殊受段偽造IP,假設使用者使用的是非透明代理,這個HTTP_X_FORWARDED_FOR參數也抓不到正確的IP吧,反正我是覺得應該要始終使用$_SERVER['REMOTE_ADDR'],要不然其他的參數在請求時都能被偽造,感覺不安全呢。

他聽到我的話無奈地對我說,他不知道對方究竟是不是不知道,但是至少那位工程師是不知道的,我看著他無奈的表情,問他,你該不會真的按照他說的去改,然後出問題了吧?他搖了搖頭,對我說,我就是怕出問題,所以那個功能沒上,那間公司也砍了我一部份的報酬,算了,反正我只想要盡快結束這個案子。

我看著他的表情,砍的那份報酬應該是不低的金額,我也就沒有繼續問下去。

最後

喝完酒後,在離開的時,我朋友對我說,那間公司的有幾隻內部的API的驗證也是這樣做的,他說雖然自己也不是專業資安人員,但是這種帶坑的公司以後還是不要接觸為妙。