自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

談一談如何在Python開(kāi)發(fā)中拒絕SSRF漏洞

安全 漏洞
特別是這兩年,大量利用SSRF攻擊內(nèi)網(wǎng)服務(wù)的案例被爆出來(lái),導(dǎo)致SSRF漏洞慢慢受到重視。這就給Web應(yīng)用開(kāi)發(fā)者提出了一個(gè)難題:如何在保證業(yè)務(wù)正常的情況下防御SSRF漏洞?

一 、SSRF漏洞常見(jiàn)防御手法及繞過(guò)方法

SSRF是一種常見(jiàn)的Web漏洞,通常存在于需要請(qǐng)求外部?jī)?nèi)容的邏輯中,比如本地化網(wǎng)絡(luò)圖片、XML解析時(shí)的外部實(shí)體注入、軟件的離線下載等。當(dāng)攻擊者傳入一個(gè)未經(jīng)驗(yàn)證的URL,后端代碼直接請(qǐng)求這個(gè)URL,將會(huì)造成SSRF漏洞。

具體危害體現(xiàn)在以下幾點(diǎn)上:

URL為內(nèi)網(wǎng)IP或域名,攻擊者將可以通過(guò)SSRF漏洞掃描目標(biāo)內(nèi)網(wǎng),查找內(nèi)網(wǎng)內(nèi)的漏洞,并想辦法反彈權(quán)限

URL中包含端口,攻擊者將可以掃描并發(fā)現(xiàn)內(nèi)網(wǎng)中機(jī)器的其他服務(wù),再進(jìn)一步進(jìn)行利用

當(dāng)請(qǐng)求方法允許其他協(xié)議的時(shí)候,將可能利用gopher、file等協(xié)議進(jìn)行第三方服務(wù)利用,如利用內(nèi)網(wǎng)的redis獲取權(quán)限、利用fastcgi進(jìn)行g(shù)etshell等

特別是這兩年,大量利用SSRF攻擊內(nèi)網(wǎng)服務(wù)的案例被爆出來(lái),導(dǎo)致SSRF漏洞慢慢受到重視。這就給Web應(yīng)用開(kāi)發(fā)者提出了一個(gè)難題:如何在保證業(yè)務(wù)正常的情況下防御SSRF漏洞?

很多開(kāi)發(fā)者認(rèn)為,只要檢查一下請(qǐng)求url的host不為內(nèi)網(wǎng)IP,即可防御SSRF。這個(gè)觀點(diǎn)其實(shí)提出了兩個(gè)技術(shù)要點(diǎn):

1.如何檢查IP是否為內(nèi)網(wǎng)IP

2.如何獲取真正請(qǐng)求的host

于是,攻擊者通過(guò)這兩個(gè)技術(shù)要點(diǎn),針對(duì)性地想出了很多繞過(guò)方法。

二、 如何檢查IP是否為內(nèi)網(wǎng)IP

這實(shí)際上是很多開(kāi)發(fā)者面臨的第一個(gè)問(wèn)題,很多新手甚至連內(nèi)網(wǎng)IP常用的段是多少也不清楚。

何謂內(nèi)網(wǎng)IP,實(shí)際上并沒(méi)有一個(gè)硬性的規(guī)定,多少到多少段必須設(shè)置為內(nèi)網(wǎng)。有的管理員可能會(huì)將內(nèi)網(wǎng)的IP設(shè)置為233.233.233.0/24段,當(dāng)然這是一個(gè)比較極端的例子。

通常我們會(huì)將以下三個(gè)段設(shè)置為內(nèi)網(wǎng)IP段,所有內(nèi)網(wǎng)內(nèi)的機(jī)器分配到的IP是在這些段中:

  1. 192.168.0.0/16 => 192.168.0.0 ~ 192.168.255.255 
  2. 10.0.0.0/8 => 10.0.0.0 ~ 10.255.255.255 
  3. 172.16.0.0/12 => 172.16.0.0 ~ 172.31.255.255 

所以通常,我們只需要判斷目標(biāo)IP不在這三個(gè)段,另外還包括一個(gè) 127.0.0.0/8 段即可。

很多人會(huì)忘記 127.0.0.0/8 ,認(rèn)為本地地址就是 127.0.0.1 ,實(shí)際上本地回環(huán)包括了整個(gè)127段。你可以訪問(wèn)http://127.233.233.233/,會(huì)發(fā)現(xiàn)和請(qǐng)求127.0.0.1是一個(gè)結(jié)果:

所以我們需要防御的實(shí)際上是4個(gè)段,只要IP不落在這4個(gè)段中,就認(rèn)為是“安全”的。

網(wǎng)上一些開(kāi)發(fā)者會(huì)選擇使用“正則”的方式判斷目標(biāo)IP是否在這四個(gè)段中,這種判斷方法通常是會(huì)遺漏或誤判的,比如如下代碼:

這是Sec-News最老版本判斷內(nèi)網(wǎng)IP的方法,里面使用正則判斷IP是否在內(nèi)網(wǎng)的幾個(gè)段中。這個(gè)正則也是我當(dāng)時(shí)臨時(shí)在網(wǎng)上搜的,很明顯這里存在多個(gè)繞過(guò)的問(wèn)題:

1. 利用八進(jìn)制IP地址繞過(guò)

2. 利用十六進(jìn)制IP地址繞過(guò)

3. 利用十進(jìn)制的IP地址繞過(guò)

4. 利用IP地址的省略寫(xiě)法繞過(guò)

這四種方式我們可以依次試試:

四種寫(xiě)法(5個(gè)例子):012.0.0.1 、 0xa.0.0.1 、 167772161 、 10.1 、 0xA000001 實(shí)際上都請(qǐng)求的是10.0.0.1,但他們一個(gè)都匹配不上上述正則表達(dá)式。

更聰明一點(diǎn)的人是不會(huì)用正則表達(dá)式來(lái)檢測(cè)IP的(也許這類(lèi)人并不知道內(nèi)網(wǎng)IP的正則該怎么寫(xiě))。Wordpress的做法是,先將IP地址規(guī)范化,然后用“.”將其分割成數(shù)組parts,然后根據(jù)parts[0]和parts[1]的取值來(lái)判斷:

其實(shí)也略顯麻煩,而且曾經(jīng)也出現(xiàn)過(guò)用進(jìn)制方法繞過(guò)的案例( WordPress <4.5 SSRF 分析 ),不推薦使用。

我后來(lái)選擇了一種更為簡(jiǎn)單的方法。眾所周知,IP地址是可以轉(zhuǎn)換成一個(gè)整數(shù)的,在PHP中調(diào)用ip2long函數(shù)即可轉(zhuǎn)換,在Python使用inet_aton去轉(zhuǎn)換。

而且IP地址是和2^32內(nèi)的整數(shù)一一對(duì)應(yīng)的,也就是說(shuō)0.0.0.0 == 0,255.255.255.255 == 2^32 - 1。所以,我們判斷一個(gè)IP是否在某個(gè)IP段內(nèi),只需將IP段的起始值、目標(biāo)IP值全部轉(zhuǎn)換為整數(shù),然后比較大小即可。

于是,我們可以將之前的正則匹配的方法修改為如下方法:

這就是一個(gè)最簡(jiǎn)單的方法,也最容易理解。

假如你懂一點(diǎn)掩碼的知識(shí),你應(yīng)該知道IP地址的掩碼實(shí)際上就是(32 - IP地址所代表的數(shù)字的末尾bit數(shù))。所以,我們只需要保證目標(biāo)IP和內(nèi)網(wǎng)邊界IP的前“掩碼”位bit相等即可。借助位運(yùn)算,將以上判斷修改地更加簡(jiǎn)單:

  1. from socket import inet_aton 
  2. from struct import unpack 
  3.   
  4. def ip2long(ip_addr): 
  5.     return unpack("!L", inet_aton(ip_addr))[0] 
  6.       
  7. def is_inner_ipaddress(ip): 
  8.     ip = ip2long(ip)     
  9.     return ip2long('127.0.0.0') >> 24 == ip >> 24 or \ 
  10.            ip2long('10.0.0.0') >> 24 == ip >> 24 or \         
  11.            ip2long('172.16.0.0') >> 20 == ip >> 20 or \        
  12.            ip2long('192.168.0.0') >> 16 == ip >> 16 

以上代碼也就是Python中判斷一個(gè)IP是否是內(nèi)網(wǎng)IP的最終方法,使用時(shí)調(diào)用is_inner_ipaddress(...)即可(注意自己編寫(xiě)捕捉異常的代碼)。

三、 host獲取與繞過(guò)

如何獲取"真正請(qǐng)求"的Host,這里需要考慮三個(gè)問(wèn)題:

1. 如何正確的獲取用戶輸入的URL的Host?

2. 只要Host只要不是內(nèi)網(wǎng)IP即可嗎?

3. 只要Host指向的IP不是內(nèi)網(wǎng)IP即可嗎?

如何正確的獲取用戶輸入的URL的Host?

第一個(gè)問(wèn)題,看起來(lái)很簡(jiǎn)單,但實(shí)際上有很多網(wǎng)站在獲取Host上犯過(guò)一些錯(cuò)誤。最常見(jiàn)的就是,使用http://233.233.233.233@10.0.0.1:8080/、http://10.0.0.1#233.233.233.233這樣的URL,讓后端認(rèn)為其Host是233.233.233.233,實(shí)際上請(qǐng)求的卻是10.0.0.1。這種方法利用的是程序員對(duì)URL解析的錯(cuò)誤,有很多程序員甚至?xí)谜齽t去解析URL。

在Python 3下,正確獲取一個(gè)URL的Host的方法:

  1. from urllib.parse import urlparse 
  2.   
  3. url = 'https://10.0.0.1/index.php' 
  4. urlparse(url).hostname 

這一步一定不能犯錯(cuò),否則后面的工作就白做了。

只要Host只要不是內(nèi)網(wǎng)IP即可嗎?

第二個(gè)問(wèn)題,只要檢查一下我們獲取到的Host是否是內(nèi)網(wǎng)IP,即可防御SSRF漏洞么?

答案是否定的,原因是,Host可能是IP形式,也可能是域名形式。如果Host是域名形式,我們是沒(méi)法直接比對(duì)的。只要其解析到內(nèi)網(wǎng)IP上,就可以繞過(guò)我們的is_inner_ipaddress了。

網(wǎng)上有個(gè)服務(wù) http://xip.io ,這是一個(gè)“神奇”的域名,它會(huì)自動(dòng)將包含某個(gè)IP地址的子域名解析到該IP。比如 127.0.0.1.xip.io ,將會(huì)自動(dòng)解析到127.0.0.1,www.10.0.0.1.xip.io將會(huì)解析到10.0.0.1:

這個(gè)域名極大的方便了我們進(jìn)行SSRF漏洞的測(cè)試,當(dāng)我們請(qǐng)求http://127.0.0.1.xip.io/info.php的時(shí)候,表面上請(qǐng)求的Host是127.0.0.1.xip.io,此時(shí)執(zhí)行is_inner_ipaddress('127.0.0.1.xip.io')是不會(huì)返回True的。但實(shí)際上請(qǐng)求的卻是127.0.0.1,這是一個(gè)標(biāo)準(zhǔn)的內(nèi)網(wǎng)IP。

所以,在檢查Host的時(shí)候,我們需要將Host解析為具體IP,再進(jìn)行判斷,代碼如下:

  1. import socket 
  2.  import re 
  3.  from urllib.parse import urlparse 
  4.  from socket import inet_aton 
  5.  from struct import unpack 
  6.    
  7.  def check_ssrf(url): 
  8.      hostname = urlparse(url).hostname 
  9.        
  10.      def ip2long(ip_addr):     
  11.          return unpack("!L", inet_aton(ip_addr))[0]     
  12.            
  13.      def is_inner_ipaddress(ip): 
  14.          ip = ip2long(ip)     
  15.          return ip2long('127.0.0.0') >> 24 == ip >> 24 or \       
  16.                 ip2long('10.0.0.0') >> 24 == ip >> 24 or \         
  17.                 ip2long('172.16.0.0') >> 20 == ip >> 20 or \    
  18.                 ip2long('192.168.0.0') >> 16 == ip >> 16 
  19.                   
  20.       try: 
  21.           if not re.match(r"^https?://.*/.*$", url):      
  22.                  raise BaseException("url format error")  
  23.           ip_address = socket.getaddrinfo(hostname, 'http')[0][4][0] 
  24.           if is_inner_ipaddress(ip_address):        
  25.                raise BaseException("inner ip address attack")    
  26.           return True, "success" 
  27.        except BaseException as e:    
  28.           return False, str(e)     
  29.        except:     
  30.           return False, "unknow error" 

首先判斷url是否是一個(gè)HTTP協(xié)議的URL(如果不檢查,攻擊者可能會(huì)利用file、gopher等協(xié)議進(jìn)行攻擊),然后獲取url的host,并解析該host,最終將解析完成的IP放入is_inner_ipaddress函數(shù)中檢查是否是內(nèi)網(wǎng)IP。

只要Host指向的IP不是內(nèi)網(wǎng)IP即可嗎?

第三個(gè)問(wèn)題,是不是做了以上工作,解析并判斷了Host指向的IP不是內(nèi)網(wǎng)IP,即防御了SSRF漏洞?

答案繼續(xù)是否定的,上述函數(shù)并不能正確防御SSRF漏洞。為什么?

當(dāng)我們請(qǐng)求的目標(biāo)返回30X狀態(tài)的時(shí)候,如果沒(méi)有禁止跳轉(zhuǎn)的設(shè)置,大部分HTTP庫(kù)會(huì)自動(dòng)跟進(jìn)跳轉(zhuǎn)。此時(shí)如果跳轉(zhuǎn)的地址是內(nèi)網(wǎng)地址,將會(huì)造成SSRF漏洞。

這個(gè)原因也很好理解,我以Python的requests庫(kù)為例。requests的API中有個(gè)設(shè)置,叫allow_redirects,當(dāng)將其設(shè)置為T(mén)rue的時(shí)候requests會(huì)自動(dòng)進(jìn)行30X跳轉(zhuǎn)。而默認(rèn)情況下(開(kāi)發(fā)者未傳入這個(gè)參數(shù)的情況下),requests會(huì)默認(rèn)將其設(shè)置為T(mén)rue:

所以,我們可以試試請(qǐng)求一個(gè)302跳轉(zhuǎn)的網(wǎng)址:

默認(rèn)情況下,將會(huì)跟蹤location指向的地址,所以返回的status code是最終訪問(wèn)的頁(yè)面的狀態(tài)碼。而設(shè)置了allow_redirects的情況下,將會(huì)直接返回302狀態(tài)碼。

所以,即使我們獲取了http://t.cn/R2iwH6d的Host,通過(guò)了is_inner_ipaddress檢查,也會(huì)因?yàn)?02跳轉(zhuǎn),跳到一個(gè)內(nèi)網(wǎng)IP,導(dǎo)致SSRF。

這種情況下,我們有兩種解決方法:

1. 設(shè)置allow_redirects=False,不允許目標(biāo)進(jìn)行跳轉(zhuǎn)

2. 每跳轉(zhuǎn)一次,就檢查一次新的Host是否是內(nèi)網(wǎng)IP,直到抵達(dá)最后的網(wǎng)址

第一種情況明顯是會(huì)影響業(yè)務(wù)的,只是規(guī)避問(wèn)題而未解決問(wèn)題。當(dāng)業(yè)務(wù)上需要目標(biāo)URL能夠跳轉(zhuǎn)的情況下,只能使用第二種方法了。

所以,歸納一下,完美解決SSRF漏洞的過(guò)程如下:

1. 解析目標(biāo)URL,獲取其Host

2. 解析Host,獲取Host指向的IP地址

3. 檢查IP地址是否為內(nèi)網(wǎng)IP

4. 請(qǐng)求URL

5. 如果有跳轉(zhuǎn),拿出跳轉(zhuǎn)URL,執(zhí)行1

0x04 使用requests庫(kù)的hooks屬性來(lái)檢查SSRF

那么,上一章說(shuō)的5個(gè)過(guò)程,具體用Python怎么實(shí)現(xiàn)?

我們可以寫(xiě)一個(gè)循環(huán),循環(huán)條件就是“該次請(qǐng)求的狀態(tài)碼是否是30X”,如果是就繼續(xù)執(zhí)行循環(huán),繼續(xù)跟進(jìn)location,如果不是,則退出循環(huán)。代碼如下:

  1. r = requests.get(url, allow_redirects=False
  2. while r.is_redirect: 
  3.     url = r.headers['location']  
  4.     succ, errstr = check_ssrf(url)  
  5.     if not succ: 
  6.         raise Exception('SSRF Attack.')  
  7.     r = requests.get(url, allow_redirects=False

這個(gè)代碼思路大概沒(méi)有問(wèn)題,但非常簡(jiǎn)陋,而且效率不高。

只要你翻翻requests的源代碼,你會(huì)發(fā)現(xiàn),它在處理30X跳轉(zhuǎn)的時(shí)候考慮了很多地方:

  • 所有請(qǐng)求放在一個(gè)requests.Session()中
  • 跳轉(zhuǎn)有個(gè)緩存,當(dāng)下次跳轉(zhuǎn)地址在緩存中的時(shí)候,就不用多次請(qǐng)求了
  • 跳轉(zhuǎn)數(shù)量有最大限制,不可能無(wú)窮無(wú)盡跳下去
  • 解決307跳轉(zhuǎn)出現(xiàn)的一些BUG等

如果說(shuō)就按照之前簡(jiǎn)陋的代碼編寫(xiě)程序,固然可以防御SSRF漏洞,但上述提高效率的方法均沒(méi)用到。

那么,有更好的解決方法么?當(dāng)然有,我們翻一下requests的源代碼,可以看到一行特殊的代碼:

hook的意思就是“劫持”,意思就是在hook的位置我可以插入我自己的代碼。我們看看dispatch_hook函數(shù)做了什么:

  1. def dispatch_hook(key, hooks, hook_data, **kwargs): 
  2.      """Dispatches a hook dictionary on a given piece of data.""" 
  3.      hookshooks = hooks or dict() 
  4.      hookshooks = hooks.get(key)     
  5.      if hooks:     
  6.          if hasattr(hooks, '__call__'): 
  7.              hooks = [hooks]     
  8.          for hook in hooks:       
  9.              _hook_data = hook(hook_data, **kwargs)       
  10.              if _hook_data is not None:        
  11.                  hook_data = _hook_data 
  12.      return hook_data 

hooks是一個(gè)函數(shù),或者一系列函數(shù)。這里做的工作就是遍歷這些函數(shù),并調(diào)用:

  1. _hook_data = hook(hook_data,**kwargs) 

我們翻翻文檔,可以找到hooks event的說(shuō)明 http://docs.python-requests.org/en/master/user/advanced/?highlight=hook#event-hooks :

文檔中定義了一個(gè)print_url函數(shù),將其作為一個(gè)hook函數(shù)。在請(qǐng)求的過(guò)程中,響應(yīng)對(duì)象被傳入了print_url函數(shù),請(qǐng)求的域名被打印了下來(lái)。

我們可以考慮一下,我們將檢查SSRF的過(guò)程也寫(xiě)為一個(gè)hook函數(shù),然后傳給requests.get,在之后的請(qǐng)求中一旦獲取response就會(huì)調(diào)用我們的hook函數(shù)。這樣,即使我設(shè)置allow_redirects=True,requests在每次請(qǐng)求后都會(huì)調(diào)用一次hook函數(shù),在hook函數(shù)里我只需檢查一下response.headers['location']即可。

說(shuō)干就干,先寫(xiě)一個(gè)hook函數(shù):

當(dāng)r.is_redirect為T(mén)rue的時(shí)候,也就是說(shuō)這次請(qǐng)求包含一個(gè)跳轉(zhuǎn)。獲取此時(shí)的r.headers['location'],并進(jìn)行一些處理,最后傳入check_ssrf。當(dāng)檢查不通過(guò)時(shí),拋出一個(gè)異常。

然后編寫(xiě)一個(gè)請(qǐng)求函數(shù)safe_request_url,意思是“安全地請(qǐng)求一個(gè)URL”。使用這個(gè)函數(shù)請(qǐng)求的域名,將不會(huì)出現(xiàn)SSRF漏洞:

我們可以看到,在第一次請(qǐng)求url前,還是需要check_ssrf一次的。因?yàn)閔ook函數(shù)_request_check_location只是檢查30X跳轉(zhuǎn)時(shí)是否存在SSRF漏洞,而沒(méi)有檢查最初請(qǐng)求是否存在SSRF漏洞。

不過(guò)上面的代碼還不算完善,因?yàn)開(kāi)request_check_location覆蓋了原有(用戶可能定義的其他hooks)的hooks屬性,所以需要簡(jiǎn)單調(diào)整一下。

最終,給出完整代碼:

  1. import socket 
  2.  import re 
  3.  import requests 
  4.  from urllib.parse import urlparse 
  5.  from socket import inet_aton 
  6.  from struct import unpack 
  7.  from requests.utils import requote_uri 
  8.    
  9.  def check_ssrf(url): 
  10.      hostname = urlparse(url).hostname 
  11.        
  12.      def ip2long(ip_addr): 
  13.          return unpack("!L", inet_aton(ip_addr))[0] 
  14.        
  15.      def is_inner_ipaddress(ip):     
  16.          ip = ip2long(ip)     
  17.          return ip2long('127.0.0.0') >> 24 == ip >> 24 or \                 
  18.                 ip2long('10.0.0.0') >> 24 == ip >> 24 or \                 
  19.                 ip2long('172.16.0.0') >> 20 == ip >> 20 or \                 
  20.                 ip2long('192.168.0.0') >> 16 == ip >> 16     
  21.                   
  22.       try:         
  23.           if not re.match(r"^https?://.*/.*$", url):             
  24.               raise BaseException("url format error")         
  25.           ip_address = socket.getaddrinfo(hostname, 'http')[0][4][0] 
  26.           if is_inner_ipaddress(ip_address):             
  27.               raise BaseException("inner ip address attack")         
  28.           return True, "success"     
  29.             
  30.        except BaseException as e:         
  31.            return False, str(e)     
  32.        except:         
  33.            return False, "unknow error" 
  34.              
  35. def safe_request_url(url, **kwargs): 
  36.     def _request_check_location(r, *args, **kwargs):         
  37.         if not r.is_redirect:             
  38.             return         
  39.               
  40.         url = r.headers['location']         
  41.           
  42.         # The scheme should be lower case...         
  43.         parsed = urlparse(url)         
  44.         url = parsed.geturl()         
  45.           
  46.         # Facilitate relative 'location' headers, as allowed by RFC 7231.         
  47.         # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')         
  48.         # Compliant with RFC3986, we percent encode the url.         
  49.         if not parsed.netloc:             
  50.             url = urljoin(r.url, requote_uri(url))         
  51.         else:             
  52.             url = requote_uri(url)         
  53.               
  54.         succ, errstr = check_ssrf(url)         
  55.         if not succ:             
  56.             raise requests.exceptions.InvalidURL("SSRF Attack: %s" % (errstr, ))     
  57.           
  58.     success, errstr = check_ssrf(url)     
  59.     if not success:         
  60.         raise requests.exceptions.InvalidURL("SSRF Attack: %s" % (errstr,))     
  61.           
  62.     all_hooks = kwargs.get('hooks', dict())     
  63.     if 'response' in all_hooks:         
  64.         if hasattr(all_hooks['response'], '__call__'):             
  65.             r_hooks = [all_hooks['response']]         
  66.         else:             
  67.             r_hooks = all_hooks['response']         
  68.               
  69.         r_hooks.append(_request_check_location)     
  70.           
  71.     else: 
  72.         r_hooks = [_request_check_location]     
  73.           
  74.     all_hooks['response'] = r_hooks    
  75.     kwargs['hooks'] = all_hooks     
  76.     return requests.get(url, **kwargs) 

外部程序只要調(diào)用safe_request_url(url)即可安全地請(qǐng)求某個(gè)URL,該函數(shù)的參數(shù)與requests.get函數(shù)參數(shù)相同。

完美在Python Web開(kāi)發(fā)中解決SSRF漏洞。其他語(yǔ)言的解決方案類(lèi)似,大家可以自己去探索。

參考內(nèi)容:

http://www.luteam.com/?p=211

http://docs.python-requests.org/

責(zé)任編輯:趙寧寧 來(lái)源: 安全客
相關(guān)推薦

2021-07-28 20:12:17

WindowsHeap內(nèi)存

2021-02-19 09:19:11

消息隊(duì)列場(chǎng)景

2022-07-04 10:51:27

數(shù)據(jù)中臺(tái)數(shù)據(jù)倉(cāng)庫(kù)

2022-02-14 22:22:30

單元測(cè)試Junit5

2021-03-15 22:42:25

NameNodeDataNode分布式

2018-08-21 14:42:29

閃存存在問(wèn)題

2020-02-19 10:45:04

開(kāi)發(fā)技能代碼

2014-07-17 10:11:53

Android LAPI谷歌

2020-10-29 08:38:07

Volodya漏洞惡意軟件

2018-01-11 09:51:34

2015-03-27 15:07:55

云計(jì)算IaaS平臺(tái)Docker

2017-11-21 14:32:05

容器持久存儲(chǔ)

2016-07-08 13:33:12

云計(jì)算

2019-01-30 10:59:48

IPv6Happy EyebaIPv4

2021-05-11 08:48:23

React Hooks前端

2011-07-28 09:22:56

Oracle WDPOracle數(shù)據(jù)庫(kù)

2021-11-23 09:45:26

架構(gòu)系統(tǒng)技術(shù)

2009-12-29 14:25:14

phpXSS漏洞

2018-09-05 15:15:58

來(lái)電顯示來(lái)電顯示欺詐身份

2020-11-20 10:22:34

代碼規(guī)范設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)