麻豆黑色丝袜jk制服福利网站-麻豆精品传媒视频观看-麻豆精品传媒一二三区在线视频-麻豆精选传媒4区2021-在线视频99-在线视频a

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > Python 中少為人知的十個安全陷阱!

Python 中少為人知的十個安全陷阱!

來源:千鋒教育
發布人:xqq
時間: 2023-11-06 19:59:06 1699271946

Python開發者們在使用標準庫和通用框架時,都以為自己的程序具有可靠的安全性。然而,在Python中,就像在任何其它編程語言中一樣,有一些特性可能會被開發者們誤解或誤用。通常而言,只有極少的微妙之處或細節會使開發者們疏忽大意,從而在代碼中引入嚴重的安全漏洞。

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

1.被優化掉的斷言

Python支持以優化的方式執行代碼。這使代碼運行得更快,內存用得更少。當程序被大規模使用,或者可用的資源很少時,這種方法尤其有效。一些預打包的Python程序提供了優化的字節碼。

然而,當代碼被優化時,所有的assert語句都會被忽略。開發者有時會使用它們來判斷代碼中的某些條件。例如,如果使用斷言來作身份驗證檢查,則可能導致安全繞過。

defsuperuser_action(request,user):

assertuser.is_super_user

#executeactionassuperuser

在這個例子中,第2行中的assert語句將被忽略,導致非超級用戶也可以運行到下一行代碼。不推薦使用assert語句進行安全相關的檢查,但我們確實在實際的項目中看到過它們。

2.MakeDirs權限

os.makdirs函數可以在操作系統中創建一個或多個文件夾。它的第二個參數mode用于指定創建的文件夾的默認權限。在下面代碼的第2行中,文件夾A/B/C是用rwx------(0o700)權限創建的。這意味著只有當前用戶(所有者)擁有這些文件夾的讀、寫和執行權限。

definit_directories(request):

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

returnHttpResponse("Done!")

在Python<3.6版本中,創建出的文件夾A、B和C的權限都是700。但是,在Python>3.6版本中,只有最后一個文件夾C的權限為700,其它文件夾A和B的權限為默認的755。

因此,在Python>3.6中,os.makdirs函數等價于Linux的這條命令:mkdir-m700-pA/B/C。有些開發者沒有意識到版本之間的差異,這已經在Django中造成了一個權限越級漏洞(cve-2022-24583),無獨有偶,這在WordPress中也造成了一個加固繞過問題。

3.絕對路徑拼接

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

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

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函數將用戶輸入的文件名構造出目標路徑。在第4行中,檢查生成的路徑是否包含”.“,防止出現路徑遍歷漏洞。

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

4.任意的臨時文件

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

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被當作臨時文件的前綴。如果攻擊者傳入的id參數是“/../var/www/test”,則會創建出這樣的臨時文件:/var/www/test_zdllj17。粗看起來,這可能是無害的,但它會為攻擊者創造出挖掘更復雜的漏洞的基礎。

5.擴展的ZipSlip

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

這就是為什么壓縮文件應該始終被視為不受信來源的原因。zipfile.extractall與zipfile.extract函數可以對zip內容進行清洗,從而防止這類路徑遍歷漏洞。

但是,這并不意味著在ZipFile庫中不會出現路徑遍歷漏洞。下面是一段解壓縮文件的代碼。

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行代碼根據用戶上傳文件的臨時路徑,創建出一個ZipFile處理器。第4-8行代碼將所有以“.html”結尾的壓縮項提取出來。第4行中的zf.namelist函數會取到zip內壓縮項的名稱。注意,只有zipfile.extract與zipfile.extractall函數會對壓縮項進行清洗,其它任何函數都不會。

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

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

6.不完整的正則表達式匹配

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

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行中,我們定義了一個匹配union或者select的模式,以檢測可能的SQL注入。這是一個糟糕的寫法,因為你可以輕易地繞過這些黑名單,但我們已經在線上的程序中見過它。在第4行中,函數re.match使用前面定義好的模式,檢查第3行中的用戶輸入內容是否包含這些惡意的值。

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

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

7.Unicode清洗器繞過

Unicode支持用多種形式來表示字符,并將這些字符映射到碼點。在Unicode標準中,不同的Unicode字符有四種歸一化方案。程序可以使用這些歸一化方法,以獨立于人類語言的標準方式來存儲數據,例如用戶名。

然而,攻擊者可以利用這些歸一化,這已經導致了Python的urllib出現漏洞(CVE-2019-9636)。下面的代碼片段演示了一個基于NFKC歸一化的跨站點腳本漏洞(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行中,用戶輸入的內容被Django的escape函數處理了,以防止XSS漏洞。在第7行中,經過清洗的輸入被NFKC算法歸一化,以便在第8-9行中通過test.html模板正確地渲染。

templates/test.html:

{{my_input|safe}}

在模板test.html中,第4行的變量my_input被標記為安全的,因為開發人員預期有特殊字符,并且認為該變量已經被escape函數清洗了。通過標記關鍵字safe,Django不會再次對變量進行清洗。

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

8.Unicode編碼碰撞

前文說過,Unicode字符會被映射成碼點。然而,有許多不同的人類語言,Unicode試圖將它們統一起來。這就意味著不同的字符很有可能擁有相同的“layout”。例如,小寫的土耳其語?(沒有點)的字符是英語中大寫的I。在拉丁字母中,字符i也是用大寫的I表示。在Unicode標準中,這兩個不同的字符都以大寫形式映射到同一個碼點。

這種行為是可以被利用的,實際上已經在Django中導致了一個嚴重的漏洞(CVE-2019-19844)。下面的代碼是一個重置密碼的示例。

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行代碼檢查這個email值,查找是否存在具有該email的用戶。如果用戶存在,則第10行代碼依據第6行中輸入的email地址,給用戶發送郵件。需要指出的是,第7-9行中對郵件地址的檢查是不區分大小寫的,使用了upper函數。

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

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

9.IP地址歸一化

在Python<3.8中,IP地址會被ipaddress庫歸一化,因此前綴的零會被刪除。這種行為乍一看可能是無害的,但它已經在Django中導致了一個高嚴重性的漏洞(CVE-2021-33571)。攻擊者可以利用歸一化繞過校驗程序,發起服務端請求偽造攻擊(SSRF,Server-SideRequestForgery)。

下面的代碼展示了如何繞過這樣的校驗器。

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行代碼獲取用戶傳入的一個IP地址,第7行代碼使用一個黑名單來檢查該IP是否為本地地址,以防止可能的SSRF漏洞。這份黑名單并不完整,僅作為示例。

第9行代碼檢查該IP是否為IPv4地址,同時將IP歸一化。在完成驗證后,第12行代碼會對該IP發起實際的請求。

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

10.URL查詢參數解析

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

在下面的例子中,我們將展示為什么這種行為會導致漏洞。假設我們正在運行一個基礎設施,其中前端是一個PHP程序,后端則是一個Python程序。

攻擊者向PHP前端發送以下的GET請求:

GEThttps://victim.com/?a=1;b=2PHP前端只識別出一個查詢參數“a”,其內容為“1;b=2”。PHP不把“;”字符作為查詢參數的分隔符。現在,前端會將攻擊者的請求直接轉發給內部的Python程序:

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

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

總結

在這篇博文中,我們介紹了10個Python安全陷阱,我們認為開發者不太了解它們。每個細微的陷阱都很容易被忽視,并在過去導致了線上程序的安全漏洞。

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

以上內容為大家介紹了Python中少為人知的十個安全陷阱!希望對大家有所幫助,如果想要了解更多Python相關知識,請關注多測師。http://www.dietsnews.net/xwzx/

tags: python培訓
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
主站蜘蛛池模板: 日本免费网站在线观看| 国产大学生一级毛片绿象| 欧美一区二区三区久久综| 中国人观看的视频播放中文| 日本不卡在线观看| 插插视频网站| 日韩三级网址| 天天爱夜夜做| 伊人影院在线视频| 黄文在线看| 天堂成人在线观看| 岳一夜要我六次| 国产一卡二卡| 日韩一区二区三区电影| 台湾swag视频在线观看| 攵女yin乱合集高h文| 又色又爽又黄的视频网站| 国产精品久久久久9999高清| 又爽又黄又无遮挡的视频在线观看| 久久精品国产99国产精偷| 最新版天堂中文在线| 国产综合精品| 国产大片免费天天看| 久久久久久久国产精品电影| 1313苦瓜网在线播| 夜先锋av资源网站| 日本欧美大码aⅴ在线播放| 色丁香在线| 五十路亲子中出中文字幕| 久久久久无码国产精品一区| 欧美成人在线视频| 狠狠天天| 再深点灬舒服灬太大了添网站| 永久免费无内鬼放心开车| 四虎成人精品免费影院| 一级片儿| 娇妻的大杂交| 日韩插插插| 视频二区三区国产情侣在线| 皇上往下边塞玉器见客 | 国产高清在线不卡|