91aaa在线国内观看,亚洲AV午夜福利精品一区二区,久久偷拍人视频,久久播这里有免费视播

<strong id="fvuar"></strong>

  • <sub id="fvuar"><dl id="fvuar"><em id="fvuar"></em></dl></sub>

    1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

      手機(jī)站
      千鋒教育

      千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

      千鋒教育

      掃一掃進(jìn)入千鋒手機(jī)站

      領(lǐng)取全套視頻
      千鋒教育

      關(guān)注千鋒學(xué)習(xí)站小程序
      隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

      當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Python 中少為人知的十個(gè)安全陷阱!

      Python 中少為人知的十個(gè)安全陷阱!

      來(lái)源:千鋒教育
      發(fā)布人:xqq
      時(shí)間: 2023-11-06 19:59:06 1699271946

      Python開(kāi)發(fā)者們?cè)谑褂脴?biāo)準(zhǔn)庫(kù)和通用框架時(shí),都以為自己的程序具有可靠的安全性。然而,在Python中,就像在任何其它編程語(yǔ)言中一樣,有一些特性可能會(huì)被開(kāi)發(fā)者們誤解或誤用。通常而言,只有極少的微妙之處或細(xì)節(jié)會(huì)使開(kāi)發(fā)者們疏忽大意,從而在代碼中引入嚴(yán)重的安全漏洞。

      在這篇博文中,我們將分享在實(shí)際Python項(xiàng)目中遇到的10個(gè)安全陷阱。我們選擇了一些在技術(shù)圈中不太為人所知的陷阱。通過(guò)介紹每個(gè)問(wèn)題及其造成的影響,我們希望提高人們對(duì)這些問(wèn)題的感知,并提高大家的安全意識(shí)。如果你正在使用這些特性,請(qǐng)一定要排查你的Python代碼!

      1.被優(yōu)化掉的斷言

      Python支持以?xún)?yōu)化的方式執(zhí)行代碼。這使代碼運(yùn)行得更快,內(nèi)存用得更少。當(dāng)程序被大規(guī)模使用,或者可用的資源很少時(shí),這種方法尤其有效。一些預(yù)打包的Python程序提供了優(yōu)化的字節(jié)碼。

      然而,當(dāng)代碼被優(yōu)化時(shí),所有的assert語(yǔ)句都會(huì)被忽略。開(kāi)發(fā)者有時(shí)會(huì)使用它們來(lái)判斷代碼中的某些條件。例如,如果使用斷言來(lái)作身份驗(yàn)證檢查,則可能導(dǎo)致安全繞過(guò)。

      defsuperuser_action(request,user):

      assertuser.is_super_user

      #executeactionassuperuser

      在這個(gè)例子中,第2行中的assert語(yǔ)句將被忽略,導(dǎo)致非超級(jí)用戶也可以運(yùn)行到下一行代碼。不推薦使用assert語(yǔ)句進(jìn)行安全相關(guān)的檢查,但我們確實(shí)在實(shí)際的項(xiàng)目中看到過(guò)它們。

      2.MakeDirs權(quán)限

      os.makdirs函數(shù)可以在操作系統(tǒng)中創(chuàng)建一個(gè)或多個(gè)文件夾。它的第二個(gè)參數(shù)mode用于指定創(chuàng)建的文件夾的默認(rèn)權(quán)限。在下面代碼的第2行中,文件夾A/B/C是用rwx------(0o700)權(quán)限創(chuàng)建的。這意味著只有當(dāng)前用戶(所有者)擁有這些文件夾的讀、寫(xiě)和執(zhí)行權(quán)限。

      definit_directories(request):

      os.makedirs("A/B/C",mode=0o700)

      returnHttpResponse("Done!")

      在Python<3.6版本中,創(chuàng)建出的文件夾A、B和C的權(quán)限都是700。但是,在Python>3.6版本中,只有最后一個(gè)文件夾C的權(quán)限為700,其它文件夾A和B的權(quán)限為默認(rèn)的755。

      因此,在Python>3.6中,os.makdirs函數(shù)等價(jià)于Linux的這條命令:mkdir-m700-pA/B/C。有些開(kāi)發(fā)者沒(méi)有意識(shí)到版本之間的差異,這已經(jīng)在Django中造成了一個(gè)權(quán)限越級(jí)漏洞(cve-2022-24583),無(wú)獨(dú)有偶,這在WordPress中也造成了一個(gè)加固繞過(guò)問(wèn)題。

      3.絕對(duì)路徑拼接

      os.path.join(path,*paths)函數(shù)用于將多個(gè)文件路徑連接成一個(gè)組合的路徑。第一個(gè)參數(shù)通常包含了基礎(chǔ)路徑,而之后的每個(gè)參數(shù)都被當(dāng)做組件拼接到基礎(chǔ)路徑后。

      然而,這個(gè)函數(shù)有一個(gè)少有人知的特性。如果拼接的某個(gè)路徑以/開(kāi)頭,那么包括基礎(chǔ)路徑在內(nèi)的所有前綴路徑都將被刪除,該路徑將被視為絕對(duì)路徑。下面的示例揭示了開(kāi)發(fā)者可能遇到的這個(gè)陷阱。

      defread_file(request):

      filename=request.POST@['filename']

      file_path=os.path.join("var","lib",filename)

      iffile_path.find(".")!=-1:

      returnHttpResponse("Failed!")

      withopen(file_path)asf:

      returnHttpResponse(f.read(),content_type='text/plain')

      在第3行中,我們使用os.path.join函數(shù)將用戶輸入的文件名構(gòu)造出目標(biāo)路徑。在第4行中,檢查生成的路徑是否包含”.“,防止出現(xiàn)路徑遍歷漏洞。

      但是,如果攻擊者傳入的文件名參數(shù)為”/a/b/c.txt“,那么第3行得到的變量file_path會(huì)是一個(gè)絕對(duì)路徑(/a/b/c.txt)。即os.path.join會(huì)忽略掉”var/lib“部分,攻擊者可以不使用“.”字符就讀取到任何文件。盡管os.path.join的文檔中描述了這種行為,但這還是導(dǎo)致了許多漏洞(CuckooSandboxEvasion,CVE-2020-35736)。

      4.任意的臨時(shí)文件

      tempfile.NamedTemporaryFile函數(shù)用于創(chuàng)建具有特定名稱(chēng)的臨時(shí)文件。但是,prefix(前綴)和suffix(后綴)參數(shù)很容易受到路徑遍歷攻擊(Issue35278)。如果攻擊者控制了這些參數(shù)之一,他就可以在文件系統(tǒng)中的任意位置創(chuàng)建出一個(gè)臨時(shí)文件。下面的示例揭示了開(kāi)發(fā)者可能遇到的一個(gè)陷阱。

      deftouch_tmp_file(request):

      id=request.GET@['id']

      tmp_file=tempfile.NamedTemporaryFile(prefix=id)

      returnHttpResponse(f"tmpfile:{tmp_file}created!",content_type='text/plain')

      在第3行中,用戶輸入的id被當(dāng)作臨時(shí)文件的前綴。如果攻擊者傳入的id參數(shù)是“/../var/www/test”,則會(huì)創(chuàng)建出這樣的臨時(shí)文件:/var/www/test_zdllj17。粗看起來(lái),這可能是無(wú)害的,但它會(huì)為攻擊者創(chuàng)造出挖掘更復(fù)雜的漏洞的基礎(chǔ)。

      5.擴(kuò)展的ZipSlip

      在Web應(yīng)用中,通常需要解壓上傳后的壓縮文件。在Python中,很多人都知道TarFile.extractall與TarFile.extract函數(shù)容易受到ZipSlip攻擊。攻擊者通過(guò)篡改壓縮包中的文件名,使其包含路徑遍歷(../)字符,從而發(fā)起攻擊。

      這就是為什么壓縮文件應(yīng)該始終被視為不受信來(lái)源的原因。zipfile.extractall與zipfile.extract函數(shù)可以對(duì)zip內(nèi)容進(jìn)行清洗,從而防止這類(lèi)路徑遍歷漏洞。

      但是,這并不意味著在ZipFile庫(kù)中不會(huì)出現(xiàn)路徑遍歷漏洞。下面是一段解壓縮文件的代碼。

      defextract_html(request):

      filename=request.FILES['filename']

      zf=zipfile.ZipFile(filename.temporary_file_path(),"r")

      forentryinzf.namelist():

      ifentry.endswith(".html"):

      file_content=zf.read(entry)

      withopen(entry,"wb")asfp:

      fp.write(file_content)

      zf.close()

      returnHttpResponse("HTMLfilesextracted!")

      第3行代碼根據(jù)用戶上傳文件的臨時(shí)路徑,創(chuàng)建出一個(gè)ZipFile處理器。第4-8行代碼將所有以“.html”結(jié)尾的壓縮項(xiàng)提取出來(lái)。第4行中的zf.namelist函數(shù)會(huì)取到zip內(nèi)壓縮項(xiàng)的名稱(chēng)。注意,只有zipfile.extract與zipfile.extractall函數(shù)會(huì)對(duì)壓縮項(xiàng)進(jìn)行清洗,其它任何函數(shù)都不會(huì)。

      在這種情況下,攻擊者可以創(chuàng)建一個(gè)文件名,例如“../../../var/www/html”,內(nèi)容隨意填。該惡意文件的內(nèi)容會(huì)在第6行被讀取,并在第7-8行寫(xiě)入被攻擊者控制的路徑。因此,攻擊者可以在整個(gè)服務(wù)器上創(chuàng)建任意的HTML文件。

      如上所述,壓縮包中的文件應(yīng)該被看作是不受信任的。如果你不使用zipfile.extractall或者zipfile.extract,你就必須對(duì)zip內(nèi)文件的名稱(chēng)進(jìn)行“消毒”,例如使用os.path.basename。否則,它可能導(dǎo)致嚴(yán)重的安全漏洞,就像在NLTKDownloader(CVE-2019-14751)中發(fā)現(xiàn)的那樣。

      6.不完整的正則表達(dá)式匹配

      正則表達(dá)式(regex)是大多數(shù)Web程序不可或缺的一部分。我們經(jīng)常能看到它被自定義的Web應(yīng)用防火墻(WAF,WebApplicationFirewalls)用來(lái)作輸入驗(yàn)證,例如檢測(cè)惡意字符串。在Python中,re.match和re.search之間有著細(xì)微的區(qū)別,我們將在下面的代碼片段中演示。

      defis_sql_injection(request):

      pattern=re.compile(r".*(union)|(select).*")

      name_to_test=request.GET@['name']

      ifre.search(pattern,name_to_test):

      returnTrue

      returnFalse

      在第2行中,我們定義了一個(gè)匹配union或者select的模式,以檢測(cè)可能的SQL注入。這是一個(gè)糟糕的寫(xiě)法,因?yàn)槟憧梢暂p易地繞過(guò)這些黑名單,但我們已經(jīng)在線上的程序中見(jiàn)過(guò)它。在第4行中,函數(shù)re.match使用前面定義好的模式,檢查第3行中的用戶輸入內(nèi)容是否包含這些惡意的值。

      然而,與re.search函數(shù)不同的是,re.match函數(shù)不匹配新行。例如,如果攻擊者提交了值aaaaaa\nunionselect,這個(gè)輸入就匹配不上正則表達(dá)式。因此,檢查可以被繞過(guò),失去保護(hù)作用。

      總而言之,我們不建議使用正則表達(dá)式黑名單進(jìn)行任何安全檢查。

      7.Unicode清洗器繞過(guò)

      Unicode支持用多種形式來(lái)表示字符,并將這些字符映射到碼點(diǎn)。在Unicode標(biāo)準(zhǔn)中,不同的Unicode字符有四種歸一化方案。程序可以使用這些歸一化方法,以獨(dú)立于人類(lèi)語(yǔ)言的標(biāo)準(zhǔn)方式來(lái)存儲(chǔ)數(shù)據(jù),例如用戶名。

      然而,攻擊者可以利用這些歸一化,這已經(jīng)導(dǎo)致了Python的urllib出現(xiàn)漏洞(CVE-2019-9636)。下面的代碼片段演示了一個(gè)基于NFKC歸一化的跨站點(diǎn)腳本漏洞(XSS,Cross-SiteScripting)。

      importunicodedata

      fromdjango.shortcutsimportrender

      fromdjango.utils.htmlimportescape

      defrender_input(request):

      user_input=escape(request.GET@['p'])

      normalized_user_input=unicodedata.normalize("NFKC",user_input)

      context={'my_input':normalized_user_input}

      returnrender(request,'test.html',context)

      在第6行中,用戶輸入的內(nèi)容被Django的escape函數(shù)處理了,以防止XSS漏洞。在第7行中,經(jīng)過(guò)清洗的輸入被NFKC算法歸一化,以便在第8-9行中通過(guò)test.html模板正確地渲染。

      templates/test.html:

      {{my_input|safe}}

      在模板test.html中,第4行的變量my_input被標(biāo)記為安全的,因?yàn)殚_(kāi)發(fā)人員預(yù)期有特殊字符,并且認(rèn)為該變量已經(jīng)被escape函數(shù)清洗了。通過(guò)標(biāo)記關(guān)鍵字safe,Django不會(huì)再次對(duì)變量進(jìn)行清洗。

      但是,由于第7行(view.py)的歸一化,字符“%EF%B9%A4”會(huì)被轉(zhuǎn)換為“<”,“%EF%B9%A5”被轉(zhuǎn)換為“>”。這導(dǎo)致攻擊者可以注入任意的HTML標(biāo)記,進(jìn)而觸發(fā)XSS漏洞。為了防止這個(gè)漏洞,就應(yīng)該在把用戶輸入做完歸一化之后,再進(jìn)行清洗。

      8.Unicode編碼碰撞

      前文說(shuō)過(guò),Unicode字符會(huì)被映射成碼點(diǎn)。然而,有許多不同的人類(lèi)語(yǔ)言,Unicode試圖將它們統(tǒng)一起來(lái)。這就意味著不同的字符很有可能擁有相同的“l(fā)ayout”。例如,小寫(xiě)的土耳其語(yǔ)?(沒(méi)有點(diǎn))的字符是英語(yǔ)中大寫(xiě)的I。在拉丁字母中,字符i也是用大寫(xiě)的I表示。在Unicode標(biāo)準(zhǔn)中,這兩個(gè)不同的字符都以大寫(xiě)形式映射到同一個(gè)碼點(diǎn)。

      這種行為是可以被利用的,實(shí)際上已經(jīng)在Django中導(dǎo)致了一個(gè)嚴(yán)重的漏洞(CVE-2019-19844)。下面的代碼是一個(gè)重置密碼的示例。

      fromdjango.core.mailimportsend_mail

      fromdjango.httpimportHttpResponse

      fromvuln.modelsimportUser

      defreset_pw(request):

      email=request.GET@['email']

      result=User.objects.filter(email__exact=email.upper()).first()

      ifnotresult:

      returnHttpResponse("Usernotfound!")

      send_mail('ResetPassword','Yournewpw:123456.','from@example.com',[email],fail_silently=False)

      returnHttpResponse("Passwordresetemailsend!")

      第6行代碼獲取了用戶輸入的email,第7-9行代碼檢查這個(gè)email值,查找是否存在具有該email的用戶。如果用戶存在,則第10行代碼依據(jù)第6行中輸入的email地址,給用戶發(fā)送郵件。需要指出的是,第7-9行中對(duì)郵件地址的檢查是不區(qū)分大小寫(xiě)的,使用了upper函數(shù)。

      至于攻擊,我們假設(shè)數(shù)據(jù)庫(kù)中存在一個(gè)郵箱地址為foo@mix.com的用戶。那么,攻擊者可以簡(jiǎn)單地傳入foo@m?x.com作為第6行中的email,其中i被替換為土耳其語(yǔ)?。第7行代碼將郵箱轉(zhuǎn)換成大寫(xiě),結(jié)果是FOO@MIX.COM。這意味著找到了一個(gè)用戶,因此會(huì)發(fā)送一封重置密碼的郵件。

      然而,郵件被發(fā)送到第6行未轉(zhuǎn)換的郵件地址,也就是包含了土耳其語(yǔ)的?。換句話說(shuō),其他用戶的密碼被發(fā)送到了攻擊者控制的郵件地址。為了防止這個(gè)漏洞,可以將第10行替換成使用數(shù)據(jù)庫(kù)中的用戶郵箱。即使發(fā)生編碼沖突,攻擊者在這種情況下也得不到任何好處。

      9.IP地址歸一化

      在Python<3.8中,IP地址會(huì)被ipaddress庫(kù)歸一化,因此前綴的零會(huì)被刪除。這種行為乍一看可能是無(wú)害的,但它已經(jīng)在Django中導(dǎo)致了一個(gè)高嚴(yán)重性的漏洞(CVE-2021-33571)。攻擊者可以利用歸一化繞過(guò)校驗(yàn)程序,發(fā)起服務(wù)端請(qǐng)求偽造攻擊(SSRF,Server-SideRequestForgery)。

      下面的代碼展示了如何繞過(guò)這樣的校驗(yàn)器。

      importrequests

      importipaddress

      defsend_request(request):

      ip=request.GET@['ip']

      try:

      ifipin["127.0.0.1","0.0.0.0"]:

      returnHttpResponse("Notallowed!")

      ip=str(ipaddress.IPv4Address(ip))

      exceptipaddress.AddressValueError:

      returnHttpResponse("Erroratvalidation!")

      requests.get('https://'+ip)

      returnHttpResponse("Requestsend!")

      第5行代碼獲取用戶傳入的一個(gè)IP地址,第7行代碼使用一個(gè)黑名單來(lái)檢查該IP是否為本地地址,以防止可能的SSRF漏洞。這份黑名單并不完整,僅作為示例。

      第9行代碼檢查該IP是否為IPv4地址,同時(shí)將IP歸一化。在完成驗(yàn)證后,第12行代碼會(huì)對(duì)該IP發(fā)起實(shí)際的請(qǐng)求。

      但是,攻擊者可以傳入127.0.001這樣的IP地址,在第7行的黑名單列表中找不到。然后,第9行代碼使用ipaddress.IPv4Address將IP歸一化為127.0.0.1。因此,攻擊者就能夠繞過(guò)SSRF校驗(yàn)器,并向本地網(wǎng)絡(luò)地址發(fā)送請(qǐng)求。

      10.URL查詢(xún)參數(shù)解析

      在Python<3.7中,urllib.parse.parse_qsl函數(shù)允許使用“;”和“&”字符作為URL的查詢(xún)變量的分隔符。有趣的是“;”字符不能被其它語(yǔ)言識(shí)別為分隔符。

      在下面的例子中,我們將展示為什么這種行為會(huì)導(dǎo)致漏洞。假設(shè)我們正在運(yùn)行一個(gè)基礎(chǔ)設(shè)施,其中前端是一個(gè)PHP程序,后端則是一個(gè)Python程序。

      攻擊者向PHP前端發(fā)送以下的GET請(qǐng)求:

      GEThttps://victim.com/?a=1;b=2PHP前端只識(shí)別出一個(gè)查詢(xún)參數(shù)“a”,其內(nèi)容為“1;b=2”。PHP不把“;”字符作為查詢(xún)參數(shù)的分隔符?,F(xiàn)在,前端會(huì)將攻擊者的請(qǐng)求直接轉(zhuǎn)發(fā)給內(nèi)部的Python程序:

      GEThttps://internal.backend/?a=1;b=2

      如果使用了urllib.parse.parse_qsl,Python程序會(huì)處理成兩個(gè)查詢(xún)參數(shù),即“a=1”和“b=2”。這種查詢(xún)參數(shù)解析的差異可能會(huì)導(dǎo)致致命的安全漏洞,比如Django中的Web緩存投毒漏洞(CVE-2021-23336)。

      總結(jié)

      在這篇博文中,我們介紹了10個(gè)Python安全陷阱,我們認(rèn)為開(kāi)發(fā)者不太了解它們。每個(gè)細(xì)微的陷阱都很容易被忽視,并在過(guò)去導(dǎo)致了線上程序的安全漏洞。

      正如前文所述,安全陷阱可能出現(xiàn)在各種操作中,從處理文件、目錄、壓縮文件、URL、IP到簡(jiǎn)單的字符串。一種常見(jiàn)的情況是庫(kù)函數(shù)的使用,這些函數(shù)可能有意想不到的行為。這提醒我們一定要升級(jí)到最新版本,并仔細(xì)閱讀文檔。在SonarSource中,我們正在研究這些缺陷,以便將來(lái)不斷改進(jìn)我們的代碼分析器。

      以上內(nèi)容為大家介紹了Python中少為人知的十個(gè)安全陷阱!希望對(duì)大家有所幫助,如果想要了解更多Python相關(guān)知識(shí),請(qǐng)關(guān)注多測(cè)師。http://www.jsszjs.cn/xwzx/

      聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
      10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
      請(qǐng)您保持通訊暢通,專(zhuān)屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
      免費(fèi)領(lǐng)取
      今日已有369人領(lǐng)取成功
      劉同學(xué) 138****2860 剛剛成功領(lǐng)取
      王同學(xué) 131****2015 剛剛成功領(lǐng)取
      張同學(xué) 133****4652 剛剛成功領(lǐng)取
      李同學(xué) 135****8607 剛剛成功領(lǐng)取
      楊同學(xué) 132****5667 剛剛成功領(lǐng)取
      岳同學(xué) 134****6652 剛剛成功領(lǐng)取
      梁同學(xué) 157****2950 剛剛成功領(lǐng)取
      劉同學(xué) 189****1015 剛剛成功領(lǐng)取
      張同學(xué) 155****4678 剛剛成功領(lǐng)取
      鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
      董同學(xué) 138****2867 剛剛成功領(lǐng)取
      周同學(xué) 136****3602 剛剛成功領(lǐng)取
      相關(guān)推薦HOT