1. 程式人生 > >獲取使用者Ip地址常見安全隱患及解決辦法

獲取使用者Ip地址常見安全隱患及解決辦法

  • 分析過程

這個來自一些專案中,獲取使用者Ip,進行使用者操作行為的記錄,是常見並且經常使用的。 一般朋友,都會看到如下通用獲取IP地址方法。

function getIP() { 
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
        $realip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { 
        $realip = $_SERVER['HTTP_CLIENT_IP']; 
    } else { 
        $realip = $_SERVER['REMOTE_ADDR']; 
        } 
        return $realip; 
    }

這個是網上常見獲取,ip函式,用這些值獲取IP,我們首先要弄清楚,這些資料是從那個地方傳過來的。

  • 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協議進行擴充套件。定義了實體頭。

HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2  所有IP用”,”分割。 HTTP_CLIENT_IP 在高階匿名代理中,這個代表了代理伺服器IP。既然是http協議擴充套件一個實體頭,並且這個值對於傳入端是信任的,信任傳入方按照規則格式輸入的。以下以x_forword_for例子加以說明,正常情況下,這個值變化過程。

image

  • 分析Bug風險點:

通過剛剛分析我們發現,其實這些變數,來自http請求的:x-forword-for欄位,以及client-ip欄位。 正常代理伺服器,當然會按rfc規範來傳入這些值。但是,當一個使用者直接構造該x-forword-for值,傳送給使用者使用者,那將會怎麼樣呢?

image圖(1)

第2步,修改x-forword-fox值,我們看看結果

image

第三步,我們再修改下看看會怎麼樣?

image

哈哈,看到上面結果沒,x-forwarded-for不光可以自己設定值,而且可以設定任意格式值。 這樣一來,好比就直接有一個可以寫入任意值的欄位。並且伺服器直接讀取,或者寫入資料庫,或者做顯示。它將帶來危險性,跟一般對入輸入沒有做任何過濾檢測,之間操作資料來源結果一樣。 並且容易帶來隱蔽性。

  • 結論:

上面getip函式,除了客戶端可以任意偽造IP,並且可以傳入任意格式IP。 這樣結果會帶來2大問題,其一,如果你設定某個頁面,做IP限制。 對方可以容易修改IP不斷請求該頁面。 其二,這類資料你如果直接使用,將帶來SQL註冊,跨站攻擊等漏洞。至於其一,可以在業務上面做限制,最好不採用IP限制。 對於其二,這類可以帶來巨大網路風險。我們必須加以糾正。

需要對getip 進行修改,得到安全的getip函式。

這類問題,其實很容易出現,以前我就利用這個騙取了大量偽裝投票。有它的隱蔽性,其實只要我們搞清楚了,某些值來龍去脈的話。理解了它的原理,修復該類bug將是非常容易。

題外話,做技術,有三步,先要會做,會解決;後要思考為什麼要這麼做,原因原理是什麼;最後是怎麼樣做,有沒有其它方法。多問問自己,你發現距離技術真理越來越近。你做事會越來越得心應手的!

我們已經意 識到直接從http_x_forwarded_for中讀取使用者IP,跟我們直接從一個get,post值中讀取其實沒有兩樣。web引數檢測裡面一個基本原則:“一切輸入都是有害的”,因此,只要是輸入我們就需要進行過濾。

  • 安全過濾後的getIP函式

  function getIP() {
    $realip = ''; //設定預設值
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $realip = $_SERVER['HTTP_CLIENT_IP'];
    } else {
        $realip = $_SERVER['REMOTE_ADDR'];
    }

    preg_match('/^((?:\d{1,3}\.){3}\d{1,3})/',$realip,$match);
    return $match?$match[0]:false;
}

以上函式,增加了IP判斷,只會讀取以Ip格式資料開頭,並且第一個滿足IP格式值。如果沒有返回false。 這樣就可以讀取到滿足格式的IP,驗證了資料的IP格式。

  • 如果我讀取網際網路的IP,使用者傳入區域網的IP,我應該直接過濾掉

我們在一些網站上面,經常可以看到提示,非法的IP地址,其實一部分是IP地址格式錯誤,一部分可能是讀取到IP地址,不滿足網際網路上面允許IP格式。 以下這個函式,是通過IANA站點規範,封裝了個函式。 通過輸入IP地址,能夠準確知道,該IP是不是可以在網際網路應用。

//網際網路允許使用IP地址
function ipType2($ip) {
    $iplist = explode(".", $ip);

    if ($iplist[0] &gt;= 224 &amp;&amp; $iplist[0] <= 239)
        return '多播';
    if ($iplist[0] &gt;= 240 &amp;&amp; $iplist[0] <= 255)
        return '保留';

    if (preg_match('/^198\.51\.100/', $ip))
        return 'TEST-NET-2,文件和示例';
    if (preg_match('/^203\.0\.113/', $ip))
        return 'TEST-NET-3,文件和示例';

    if (preg_match('/^192\.(18|19)\./', $ip))
        return '網路基準測試';

    if (preg_match('/^192\.168/', $ip))
        return '專用網路[內部網]';

    if (preg_match('/^192\.88\.99/', $ip))
        return 'ipv6to4中繼';
    if (preg_match('/^192\.0\.2\./', $ip))
        return 'TEST-NET-1,文件和示例';
    if (preg_match('/^192\.0\.0\./', $ip))
        return '保留(IANA)';
    if (preg_match('/^192\.0\.0\./', $ip))
        return '保留(IANA)';

    if ($iplist[0] == 172 &amp;&amp; $iplist[1] <= 31 && $iplist[1] >= 16)
        return '專用網路[內部網]';

    if ($iplist[0] == 169 &amp;&amp; $iplist[1] == 254)
        return '鏈路本地';
    if ($iplist[0] == 127)
        return '環回地址';
    if ($iplist[0] == 10)
        return '專用網路[內部網]';
    if ($iplist[0] == 0)
        return '本網路(僅作為源地址時合法)';

    return 'InterNet網地址';
}

當你輸入IP地址,它返回是“’InterNet網地址’ ,那麼這個IP地址不光格式正確,而且是網際網路上面合法的IP地址。 這個函式很複雜,其實就是排除很多非網際網路使用IP地址。 我們常見的192,127,10開頭地址估計都很熟悉了。 但實際上,很多IP地址是保留的,或者留作它用。 不能作為網際網路 IP使用。 有了以上兩個函式,我們不光可以讀到正確格式IP地址,還能夠保證讀到是網際網路上面IP地址。 以上是工作中常使用的函式,歡迎朋友們交流!

相關推薦

獲取使用者Ip地址常見安全隱患解決辦法

分析過程 這個來自一些專案中,獲取使用者Ip,進行使用者操作行為的記錄,是常見並且經常使用的。 一般朋友,都會看到如下通用獲取IP地址方法。 function getIP() { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

C# NTP 時鐘同步,獲取指定IP地址的系統時間錯誤問題解決

為了實現內網間機子的時鐘同步,需要用到NTP協議的,所以做了一下這方面工作。 實現獲取指定IP系統時間的程式碼在網上有現成的: 呼叫的方法如下: var client = new SNTPTimeClient("127.0.0.1", "123"); client.

常見web安全隱患解決方案

Abstract 有關於WEB服務以及web應用的一些安全隱患總結資料。 1. 常見web安全隱患 1.1.       完全信賴使用者提交內容   開發人員決不能相信一個來自外部的資料。不管它來自使用者提交表單,檔案系統的檔案或者環境變數,任何資料都不能簡單的想

asp.net MVC 常見安全問題解決方案

container coo baidu his ring article 調試工具 並且 part asp.net MVC 常見安全問題及解決方案一.CSRF (Cross-site request forgery跨站請求偽造,也被稱為“one click attack”或

網站10大常見安全漏洞解決方案

一般來說牛逼點的地方都會通過安全裝置來確保網路環境的安全,所以之前我們也都認為程式設計師不需要過多的考慮網站安全問題。實際上隨著做了幾個事業單位的網站之後,也逐漸發現有些方面還是需要程式設計師注意的。1. SQL注入 安全等級★★★★★幾乎每一個網站後臺開發人員都聽到的一個詞

樹莓派ping主機名比IP地址慢的原因解決方法

在樹莓派的Debian系統裡面訪問網路很慢,而且ping www.baidu.com響應非常非常的慢,但是直接用www.baidu.com的IP去ping,響應感覺超快,尤其是使用引數A,格式:ping -A  ip。我個人認為肯定是域名解析出了問題。 1、debi

edge瀏覽器識別ip地址為手機號的解決辦法

phone 技術 cnblogs orm 今天 mat content com 天突 edge瀏覽器識別ip地址為手機號的解決辦法 今天突然發現類似101.231.70.242的ip地址會在edge瀏覽器裏面識別為可點擊的鏈接,後來看了一下,原因就是被識別為手機號了,因為我

Linux客戶機訪問FTP服務器常見的問題解決辦法

哪些 管理員 策略 src 用戶模式 iptable 我們 共享 還需要 在Linux系統中,搭建一個服務,就是修改其配置文件,一般情況下,配置文件的修改出現問題的概率不大,多半是一些其他因素導致客戶機與服務器之間訪問出現問題,下面就針對客戶機訪問FTP服務器常出現的一些問

CSS常見相容性問題解決辦法彙總

我們都知道,不同版本瀏覽器對css的解析是有些分別的,特別是IE6,和IE7.雖然現在使用老版本的人數不多,但是還是有部分人在使用,我們並不能完全忽略這群使用者。如下所示:我們還是應該瞭解一下這些瀏覽器相容問題。 問題一:在IE6元素浮動,如果寬度需要內容

java中ArrayList使用remove刪除元素時幾種常見的問題解決辦法

一,for迴圈使用remove()刪除座標來刪除元素。 問題現象:迴圈的時候被刪除元素的下個元素不能讀取到。程式碼現象如下: List<String> testList1 = new ArrayList<Stri

css常見的bug解決辦法

1、圖片在IE6及以下有邊框    解決:給img{border:0 none} 2、div插入圖片有間隙    解決:(1)div{font-size:0}     (2)img{display:block} 3、雙倍浮向,在IE6及以下版本,浮動的元素,有設定marg

PB常見編譯出錯解決辦法(一)

Error: Ram start overlaps rom binary   Rom end  : 0x8df9ba1c   Ram start: 0x8de29000   NK   physfirst 8c200000   physlast  8df9ba1c   ulRA

在IDEA中使用JDBC獲取資料庫連線時的報錯解決辦法

在IDEA中使用JDBC獲取資料庫連線時,有時會報錯Sat Dec 19 19:32:18 CST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. Accordi

Android 獲取手機IP地址的兩種方式常見問題

1.使用WIFI 新增許可權 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission

Linux下編程獲取本地IP地址常見方法

print 拓撲 htons 技術 ams 輸出 per arpa res 轉載於:http://blog.csdn.net/k346k346/article/details/48231933   在進行linux網絡編程時,經常用到本機IP地址。本文羅列一下常見方法,以備

Linux下程式設計獲取本地IP地址常見方法

轉載於:http://blog.csdn.net/k346k346/article/details/48231933   在進行linux網路程式設計時,經常用到本機IP地址。本文羅列一下常見方法,以備不時之需。 獲取本機IP地址,是一個相當靈活的操作,原因是網路地址的設定非常靈活而且都是允

根據HttpServletRequest獲取使用者IP地址判斷當前IP是否是內網IP

最近專案上遇到了獲取登入IP並判斷是否是內網IP的需求,在此整理一下實現方法。 首先使用者登入後,我們可以通過HttpServletRequest的request物件獲取使用者IP,但這些IP不一定是使用者的真實IP。 下面是一些常見請求頭: X-Forwarded-F

php獲取真實ip地址原理實現

1、HTTP_X_FORWARDED_FOR 是使用者到達最終訪問地時經過的路徑訪問點(包括自身和使用的多層代理)的IP列表。依然取決於代理的設定,可通過http頭偽造 2、HTTP_CLIENT_IP 是代理伺服器設定傳送的HTTP頭,代表你的客戶端的真實I

獲取請求主機IP地址,如果通過代理進來,則透過防火墻獲取真實IP地址

cas return ++ strip dex except servlet desc 請求 /** * 獲取請求主機IP地址,如果通過代理進來,則透過防火墻獲取真實IP地址; * @Title: getIpAddress * @Descr

Delphi獲取公網IP地址函數

fin .get style phi del 獲取公網ip final end and uses IdHTTP; function GetPublicIP: string; var strIP, URL: string; iStart, iEnd: Integer; My