Python編碼規(guī)范修煉與代碼安全
在編寫符合規(guī)范的代碼以提高可閱讀性時,注意代碼的安全問題也不能忽視。
互聯(lián)網(wǎng)企業(yè)的核心就是產(chǎn)品档玻,如果對軟件產(chǎn)品安全不夠重視,受到的經(jīng)濟(jì)損失將是無法估計的茫藏,有可能影響著企業(yè)的生死存亡误趴。
當(dāng)相關(guān)開發(fā)者心中沒有安全的相關(guān)概念、項目的開發(fā)务傲,上線及迭代更新沒有相應(yīng)的規(guī)范等等凉当,這些問題都將會是導(dǎo)致出現(xiàn)安全問題
理論上來講對于安全,無論企業(yè)規(guī)模大小售葡,無論企業(yè)產(chǎn)品的重要程度如何看杭,注重軟件安全是非常有必要的。
- 通用安全開發(fā)規(guī)范
- python安全編碼規(guī)范
- web編程安全規(guī)范
一挟伙,通用安全開發(fā)規(guī)范
輸入驗證
- 對所有輸入的信息和內(nèi)容都需要做必要驗證,包括數(shù)據(jù)類型楼雹,長度和范圍等
- 禁止向exec()/eval()方法傳遞不可信、未凈化的數(shù)據(jù)(當(dāng)參數(shù)中包含空格尖阔,雙引號贮缅,以-或者/符號開頭表示一個參數(shù)開關(guān)時,可能會導(dǎo)致參數(shù)注入漏洞)
- 必要時可以考慮在python中禁用exec或eval方法
輸出編碼
- 必要時對所有輸出字符進(jìn)行編碼
- 特別包括SQL诺祸,XML携悯,HTML,JavaScript等內(nèi)容
- 對于操作系統(tǒng)命令筷笨,凈化所有不可信數(shù)據(jù)輸出
異常處理
- 禁止在異常中泄露敏感信息(錯誤信息憔鬼,路徑,IP胃夏,版本轴或,架構(gòu)等)
- 發(fā)生異常時要恢復(fù)到之前的對象狀態(tài)(業(yè)務(wù)操作失敗時,進(jìn)行回滾業(yè)務(wù)仰禀;或者避免去修改對象狀態(tài)照雁,維持對象狀態(tài)一致性)
身份驗證
- 除了那些特定設(shè)為“公開”的內(nèi)容以外,對所有的網(wǎng)頁和資源都要求進(jìn)行身份驗證答恶,并正確設(shè)計身份驗證功能
- 所有的身份驗證過程必須在服務(wù)器后端上執(zhí)行
- 所有的身份驗證控制應(yīng)當(dāng)安全的處理未成功的身份驗證饺蚊,比如給出錯誤模糊提示,隱藏敏感信息
- 登錄入口應(yīng)具有防止暴力猜解及撞庫猜解(利用已泄漏的密碼字典進(jìn)行批量登錄嘗試)的措施悬嗓,超過設(shè)定失敗次數(shù)需要啟用鎖定或圖片隨機碼進(jìn)行訪問限制
- 在執(zhí)行關(guān)鍵操作(如個人信息密碼修改操作)時污呼,應(yīng)對用戶身份進(jìn)行再次驗證
- 為高度敏感或重要的交易賬戶使用多因子身份驗證機制,如支付密碼包竹、短信驗證碼等
短信驗證碼
- 發(fā)送頻率控制(建議60s獲取一次)
- 驗證碼有效期(建議60s內(nèi)有效燕酷,發(fā)短信時進(jìn)行友好提示)
- 復(fù)雜度(短信驗證碼建議6位數(shù)字)
- 一次一用籍凝,次數(shù)限制,防止被黑客惡意消耗短信
- 在前端校驗只能作為輔助手段苗缩,很容易被繞過饵蒂,必須使用服務(wù)端代碼對輸入數(shù)據(jù)進(jìn)行最終校驗
圖形驗證碼
- 一次一用
- 驗證碼有效期(10分鐘內(nèi)有效,可根據(jù)場景兼容安全和體驗靈活設(shè)置)
- 復(fù)雜度(4位及以上數(shù)字酱讶、字母交替)退盯,根據(jù)需要也可采用當(dāng)下流行的拖拽驗證碼或計算值的驗證方式
- 服務(wù)器端進(jìn)行認(rèn)證
- 從用戶體驗和安全角度出發(fā),可設(shè)計為當(dāng)用戶輸3次錯誤密碼后自動彈出驗證碼輸入框進(jìn)行驗證操作
密碼管理
- 所有密碼不得明文處理浴麻,必須選擇加密
- 禁止使用私有或者弱加密算法得问,推薦使用AES: 128位,RSA: 2048位软免,DSA: 2048位
- 密碼重設(shè)和更改操作,需要進(jìn)行二次合法身份驗證
- 密碼重設(shè)時焚挠,應(yīng)對注冊手機號和郵箱進(jìn)行有效驗證膏萧,鏈接只能發(fā)送到預(yù)先注冊的郵件地址或預(yù)先綁定的手機號
- 臨時密碼和鏈接應(yīng)設(shè)計一個短暫的有效期(比如5分鐘),防止暴力破解
- 當(dāng)密碼重新設(shè)置時蝌衔,應(yīng)短信通知用戶是否是本人在操作榛泛,告知安全風(fēng)險
- 密碼復(fù)雜度設(shè)置:建議8個字符以上,包含字母噩斟、數(shù)字及特殊字符等
會話安全
- 用戶登出后應(yīng)立即清理會話及其相關(guān)登錄信息
- 注銷功能應(yīng)當(dāng)完全終止相關(guān)的會話或連接
- 會話cookie應(yīng)設(shè)計有效期曹锨,超時后立即失效
- 當(dāng)設(shè)計允許用戶在多渠道終端同時登錄時,建議應(yīng)進(jìn)行常用設(shè)備登錄限制
訪問控制
- 將具有特權(quán)的邏輯從其他應(yīng)用程序代碼中隔離開
- 限制只有授權(quán)的用戶才能訪問文件資源剃允,url等
- 服務(wù)器端執(zhí)行的訪問控制規(guī)則和前端實施的訪問控制規(guī)則必須匹配
- 服務(wù)器中創(chuàng)建文件時需指定合理的訪問權(quán)限(讀/寫/可執(zhí)行)
- 當(dāng)權(quán)限重新設(shè)置發(fā)生變更時沛简,應(yīng)記錄好日志,并短信通知用戶是否是本人在操作斥废,告知可能存在的安全風(fēng)險
日志規(guī)范
- 不要在日志中保存敏感信息椒楣,包括系統(tǒng)指紋信息、會話標(biāo)識符牡肉、賬號密碼捧灰、證件、ID等
- 確保日志記錄包含了重要的日志事件數(shù)據(jù)
- 記錄所有的管理功能操作行為统锤,包含但不限于安全配置設(shè)置的變更
- 禁止將日志直接保存在可被瀏覽器訪問到的WEB目錄中
SQL注入
- 永遠(yuǎn)不要信任用戶的輸入毛俏,要對用戶的所有輸入進(jìn)行校驗,包含SQL語句的過濾和轉(zhuǎn)義
- 永遠(yuǎn)不要使用動態(tài)拼裝SQL饲窿,可以使用參數(shù)化的SQL或者使用存儲過程進(jìn)行數(shù)據(jù)查詢存取
- 永遠(yuǎn)不要使用管理員權(quán)限進(jìn)行數(shù)據(jù)庫連接煌寇,為每個應(yīng)用使用單獨的非特權(quán)權(quán)限,且配置有限的數(shù)據(jù)庫連接數(shù)
- 不要把敏感信息明文存放免绿,采用加密或者哈希唧席、混淆等方式對敏感信息進(jìn)行脫敏存儲
- 應(yīng)用的異常信息應(yīng)不帶有敏感信息,給出盡可能少的提示
XSS跨站腳本攻擊
- 對輸入的數(shù)據(jù)進(jìn)行過濾和轉(zhuǎn)義,包含但不限于< >" ' % ( ) & + \ ' "等危險特殊字符
- 數(shù)據(jù)添加到html元素屬性或者內(nèi)容中時淌哟,對數(shù)據(jù)進(jìn)行HTML轉(zhuǎn)義
- 數(shù)據(jù)添加到script腳本中時迹卢,對數(shù)據(jù)進(jìn)行script轉(zhuǎn)義
- 數(shù)據(jù)添加到style中時,對數(shù)據(jù)進(jìn)行css轉(zhuǎn)義
CSRF跨站請求偽造
- 建議在每個關(guān)鍵表單中引入了CSRF Token驗證(會話中生成的隨機串徒仓,提交后校驗)
- 在關(guān)鍵表單提交時要求用戶進(jìn)行二次身份驗證(錄入密碼腐碱、插KEY、輸入圖片驗證碼掉弛、短信驗證碼)
- 對請求referer做驗證(比如跨域症见、系統(tǒng)內(nèi)部應(yīng)用)
文件上傳安全
- 上傳操作應(yīng)設(shè)計身份驗證機制,并進(jìn)行合法身份校驗
- 只允許上傳滿足業(yè)務(wù)需要的相關(guān)文檔類型
- 通過檢查文件頭信息殃饿,比如JPEG (jpg)文件頭信息(十六進(jìn)制):FFD8FF谋作,驗證上傳文檔是否是所期待的類型
- 不要把文件保存在與應(yīng)用程序相同的 Web 環(huán)境中,建議將文件保存在專用的文檔服務(wù)器中乎芳,單獨給文檔服務(wù)器配置域名訪問更好
- 限制上傳任意可能被 Web 服務(wù)器解析的文件 遵蚜,比如jsp、php奈惑,py等
- 上傳文件以二進(jìn)制形式下載吭净,建議不提供直接訪問(防止木馬文件直接執(zhí)行)
- 禁止授予上傳文件存儲目錄的可執(zhí)行權(quán)限
- 禁止客戶端自定義文件上傳/下載路徑(如:使用../../../../進(jìn)行跳轉(zhuǎn))
- 文件上傳后重命名(需根據(jù)業(yè)務(wù)實際需求制定命名規(guī)則)
接口安全
- 調(diào)用方來源IP控制,比如可通過防火墻肴甸、主機host deny寂殉、Nginx deny等技術(shù)措施進(jìn)行實施
- 調(diào)用方身份認(rèn)證,比如key原在、secret友扰、證書等技術(shù)措施進(jìn)行實施
- 調(diào)用參數(shù)認(rèn)證,需設(shè)計參數(shù)容錯機制晤斩,避免出現(xiàn)參數(shù)可遍歷敏感數(shù)據(jù)安全問題
- 采用數(shù)字簽名保障接口身份來源可信焕檬,數(shù)據(jù)防篡改
- 調(diào)用方權(quán)限控制設(shè)置,調(diào)用頻率澳泵、有效期進(jìn)行控制
二实愚,Python安全編碼規(guī)范
Python開發(fā)本身要注意的有,一些危險函數(shù),危險模塊的調(diào)用處理等兔辅,以下是代碼中各種容易引發(fā)安全問題的調(diào)用和處理方式腊敲。
1.危險的函數(shù)調(diào)用
- eval,任何時候都不要使用eval维苔,這個函數(shù)會到時代碼上下文出現(xiàn)不可預(yù)期的變化碰辅,并且在eval的內(nèi)容不確定時可能會導(dǎo)致黑客直接通過植入代碼控制進(jìn)程甚至是服務(wù)器。如非得使用該函數(shù)介时,推薦使用 ast.literal_eval 來進(jìn)行操作没宾。
- exec凌彬,execfile, 該statement用于在python中執(zhí)行了一段代碼并控制上下文,并可能導(dǎo)致產(chǎn)生與eval相同的問題。
- pickle.*, marshal.*(包含pickle和cpickle)循衰,pickle相關(guān)命令用于對包裝當(dāng)前上下文的一個代碼處理邏輯铲敛,并序列化成一個字符串。在使用pickle.loads一段pickle序列化后的字符串時会钝,如序列化字符串包含 reduce 魔術(shù)方法伐蒋,則會導(dǎo)致pickle執(zhí)行reduce中的內(nèi)容,該序列化內(nèi)容如被修改迁酸,則會導(dǎo)致在反序列化時觸發(fā)惡意代碼的注入先鱼。
- os.system, os.exec* , os.popen* , posix.system, ctypes.CDLL等, 在Python中以下類型的方法均可以調(diào)用系統(tǒng)命令(ctypes.CDLL包含的_load_library方法存在命令注入),在使用時奸鬓,需要對傳慘內(nèi)容進(jìn)行檢查焙畔。
2.危險的處理方式
- 對于跨語言進(jìn)行RPC通信時(如查詢SQL時),盡量使用ORM后的接口調(diào)用全蝶,盡可能避免使用原生的查詢代碼闹蒜。
- 舉例: sql = ‘select smcolumn from smtable where name="%s"’ % columnquery
- 當(dāng)columnquery傳入可閉合sql語句時,就可以使得SQL條件跳出當(dāng)前邏輯抑淫,從而執(zhí)行更多其他類型的數(shù)據(jù)。如 columnquery='abc" and sleep(1e10000) # 如此即可掛起整個SQL事物姥闪,觸發(fā)異常始苇。
- 在使用SQL時,請使用預(yù)編譯綁定方式傳入查詢參數(shù)筐喳,一是可以加快sql的查詢催式,二是可以避免大多數(shù)危險的突破SQL邏輯的語句產(chǎn)生
- 同理適用于其他非結(jié)構(gòu)化控制的指令器(bash、mongodb避归、redis?exec)等
- 也同理適用于操作系統(tǒng)sh命令的執(zhí)行等
- 舉例: sql = ‘select smcolumn from smtable where name="%s"’ % columnquery
- 對于正則處理荣月,需要預(yù)估傳入正則的內(nèi)容大小以及正則的處理模式,如有大量文本傳入正則解析時梳毙,會導(dǎo)致CPU飛起來哺窄,影響其他協(xié)程、事物的處理账锹。
- 在使用XML解析時候萌业,請關(guān)閉外部實體的解析邏輯來防止XXE攻擊
- 對于入?yún)⒌目刂疲埵褂谩皺z查”而非“過濾”奸柬,來避免錯誤的過濾導(dǎo)致的檢查繞過生年。
3.運行時安全
- 請盡可能的使用vitualenv,并指定site-package目錄廓奕,以避免可能產(chǎn)生的攻擊抱婉。
- 盡可能的將進(jìn)程的啟動權(quán)限壓到非root用戶档叔,如遇到啟動端口等高權(quán)方式,請使用setuid將進(jìn)程降權(quán)蒸绩。
三衙四,web編程安全規(guī)范
對應(yīng)Web編程中安全概念在python web框架中的實現(xiàn)。url跳轉(zhuǎn)侵贵,目錄遍歷届搁,任意文件讀取也需要考慮在內(nèi)。針對不同的框架也需要窍育。
Flask 安全
- 使用Flask-Security
- 直接生成 HTML 而不通過使用Jinja2
- 不要在用戶提交的數(shù)據(jù)上調(diào)用Markup
- 使用 Content-Disposition: attachment 標(biāo)頭去避免上傳html文件
- 防止CSRF卡睦,flask本身沒有實現(xiàn)該功能
Django 安全
可參考phithon的博客,有較多相關(guān)資料漱抓。
- 關(guān)閉DEBUG模式
- 妥善保存SECRET_KEY
- 設(shè)置SECURE_BROWSER_XSS_FILTER輸出x-xss-protection頭表锻,讓瀏覽器強制開啟XSS過濾
- 設(shè)置SECURE_SSL_REDIRECT讓HTTP的請求強制跳轉(zhuǎn)到HTTPS
- 設(shè)置SESSION_COOKIE_SECURE使Cookie為Secure,不允許在HTTP中傳輸
- 設(shè)置CSRF_COOKIE_SECURE使CSRF Token Cookie設(shè)置為Secure乞娄,不允許在HTTP中傳輸
- 設(shè)置X_FRAME_OPTIONS返回X-FRAME-OPTIONS: DENY頭瞬逊,以防止被其他頁面作為框架加載導(dǎo)致ClickJacking
- 部署前運行安全性檢測 django-admin.py checksecure --settings=production_settings
以上就是為大家整理的關(guān)于代碼安全的問題,希望小伙伴們在編寫符合規(guī)范的代碼以提高可閱讀性時仪或,也能注意代碼的安全問題确镊。
如果喜歡或者對你有幫助的小伙伴,歡迎大家關(guān)注我的公眾號:后廠程序員范删,并分享蕾域、點贊、在看 三連