Java安全編碼指南的筆記
閱讀Secure Coding Guidelines for Java SE時(shí)的筆記。
FUNDAMENTALS
Guideline 0-0 / FUNDAMENTALS-0: Prefer to have obviously no flaws rather than no obvious flaws
盡可能消除缺陷。
Guideline 0-1 / FUNDAMENTALS-1: Design APIs to avoid security concerns
Guideline 0-2 / FUNDAMENTALS-2: Avoid duplication
老生常談,項(xiàng)目中應(yīng)當(dāng)消除重復(fù)代碼和重復(fù)數(shù)據(jù),相同用途的代碼和數(shù)據(jù),應(yīng)當(dāng)只保留一份。
重復(fù)出現(xiàn)的代碼,有助于提高程序員的產(chǎn)出,但同樣引入了很多無形的工作,比如驗(yàn)證的工作、修改bug的工作等。
對于后來的開發(fā)者,在項(xiàng)目中遇到很多功能、近似的代碼,將無從下手,不知該如何是好。
Guideline 0-3 / FUNDAMENTALS-3: Restrict privileges
合理控制代碼的運(yùn)行時(shí)權(quán)限。
Guideline 0-4 / FUNDAMENTALS-4: Establish trust boundaries
構(gòu)建信任邊界。
數(shù)據(jù)跨越信任邊界時(shí),需要執(zhí)行必要的校驗(yàn)和驗(yàn)證。
數(shù)據(jù)在信任邊界之間傳輸時(shí),需要采用安全傳輸通道,同時(shí)執(zhí)行必要的完整性、一致性等檢查。
Guideline 0-5 / FUNDAMENTALS-5: Minimise the number of permission checks
通過良好的設(shè)計(jì)和實(shí)現(xiàn),精簡權(quán)限檢查的數(shù)量。
Guideline 0-6 / FUNDAMENTALS-6: Encapsulate
良好的設(shè)計(jì)和實(shí)現(xiàn),通過封裝來保護(hù)數(shù)據(jù),規(guī)避意外或者惡意的訪問。
比如定義Java Bean時(shí):
- 提供getter/setter方法來訪問成員。
- 對于容器類的成員,避免暴露成員的引用。
Guideline 0-7 / FUNDAMENTALS-7: Document security-related information
完善API的文檔,提供安全相關(guān)的說明,比如:
- 調(diào)用API需要具備的權(quán)限。
- 涉及安全的相關(guān)異常。
- 調(diào)用API時(shí)的注意事項(xiàng),比如前置條件、調(diào)用后的清理操作等。
- API可能拋出的異常,以及對應(yīng)的場景。
Guideline 0-8 / FUNDAMENTALS-8: Secure third-party code
及時(shí)更新項(xiàng)目中使用的第三方軟件包的版本,獲取其安全更新,依據(jù)其安全方面的建議,更新當(dāng)前項(xiàng)目的配置,持續(xù)看護(hù)項(xiàng)目的安全性。
記憶里,有一些開源軟件引入了大規(guī)模的整改工作,比如:
- Struts2
Apache Struts is a free, open-source, MVC framework for creating elegant, modern Java web applications. It favors convention over configuration, is extensible using a plugin architecture, and ships with plugins to support REST, AJAX and JSON.
- fastjson
Fastjson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Fastjson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
FASTJSON 2.0.x has been released, faster and more secure, we recommend you upgrade to the latest version.
Denial of Service
拒絕服務(wù),指的是受攻擊的服務(wù),無法響應(yīng)系統(tǒng)的友好客戶發(fā)起的請求。
常見的表現(xiàn),比如:
- 大量的惡意攻擊,直接導(dǎo)致服務(wù)集群中的主機(jī)下線,從而無法提供服務(wù)。
- 大量的惡意攻擊,擠占了服務(wù)集群中主機(jī)的硬件資源,比如CPU、內(nèi)存、存儲、網(wǎng)絡(luò)帶寬等
- 導(dǎo)致無法響應(yīng)友好客戶的請求。
- 導(dǎo)致響應(yīng)友好客戶的請求過程中,消耗的時(shí)間或者資源超出預(yù)期。
- 正常的業(yè)務(wù)請求,但觸發(fā)了應(yīng)用軟件中的問題
- 導(dǎo)致無法正常響應(yīng)其他友好客戶的請求。
- 導(dǎo)致響應(yīng)友好客戶的請求過程中,消耗的時(shí)間或者資源超出預(yù)期。
Guideline 1-1 / DOS-1: Beware of activities that may use disproportionate resources
一些對資源使用量超出預(yù)期的行為,比如:
- 超大的圖片。
- 整型數(shù)據(jù),運(yùn)算溢出類的現(xiàn)象。
- zip文件炸彈。
- XML解析時(shí),處理內(nèi)部實(shí)體、外部實(shí)體時(shí)引入的問題。
- 使用XPath解析XML時(shí),消耗過多CPU時(shí)間。
- 使用Hash表時(shí),同一個(gè)hash值映射到數(shù)量眾多的value,導(dǎo)致訪問的時(shí)間成本從常數(shù)上升為N平方。
- 正則表達(dá)式,不恰當(dāng)或者錯(cuò)誤的使用方法,導(dǎo)致過多的backtrack。
- Java的反序列化技術(shù),可能消耗過多的CPU時(shí)間,或者占用過多的內(nèi)存。
- 輸出日志時(shí),不恰當(dāng)?shù)娜罩炯墑e,輸出的對象過大,或者輸出量過多,可能導(dǎo)致日志框架占用過多的資源,產(chǎn)生大量的日志文件。
- 代碼中存在的循環(huán),退出條件存在瑕疵,可能出現(xiàn)過高的循環(huán)次數(shù)或者死循環(huán),從而占用過多的CPU資源,以及其它資源。
- 加載惡意代碼時(shí),惡意代碼中的行為可能導(dǎo)致應(yīng)用軟件占用過多的系統(tǒng)資源。
處理外部輸入的資源時(shí),應(yīng)當(dāng)依據(jù)業(yè)務(wù)特點(diǎn),完善輸入數(shù)據(jù)的驗(yàn)證和校驗(yàn),盡可能提前攔截異常數(shù)據(jù)。
前期加強(qiáng)對數(shù)據(jù)有效性的校驗(yàn),可以降低后期應(yīng)用軟件在生產(chǎn)環(huán)境出現(xiàn)問題的可能性。
Guideline 1-2 / DOS-2: Release resources in all cases
系統(tǒng)資源,比如鎖、內(nèi)存、文件的輸入和輸出流、網(wǎng)絡(luò)的輸入和輸出流等,使用完畢之后需要及時(shí)關(guān)閉,保證資源沒有泄漏。
Guideline 1-3 / DOS-3: Resource limit checks should not suffer from integer overflow
關(guān)注代碼中存在的整型數(shù)值的運(yùn)算,消除運(yùn)算溢出對應(yīng)用軟件的影響。
Guideline 1-4 / DOS-4: Implement Robust Error/Exceptions handling for services
Java的Exception是語言層面提供的特性,在構(gòu)建應(yīng)用軟件時(shí),架構(gòu)師團(tuán)隊(duì)?wèi)?yīng)當(dāng)定義統(tǒng)一的使用和處理規(guī)范,指導(dǎo)開發(fā)團(tuán)隊(duì)采用一致的方式使用Exception。
Confidential Information
系統(tǒng)的關(guān)鍵數(shù)據(jù),應(yīng)當(dāng)受限使用,控制暴露的范圍。
Guideline 2-1 / CONFIDENTIAL-1: Purge sensitive information from exceptions
Java的Exception對象可能攜帶了敏感數(shù)據(jù),比如文件路徑,對于惡意攻擊者,可以構(gòu)建不同的業(yè)務(wù)請求,多次嘗試之后,逐步猜測應(yīng)用軟件所在安裝目錄或者主機(jī)系統(tǒng)的布局。
Java的Exception對象包含了調(diào)用棧,相關(guān)信息假如暴露給惡意攻擊者,可以從棧信息中推測當(dāng)前應(yīng)用軟件使用的軟件和技術(shù),從而采用更有針對性的攻擊方法,提升攻擊的效率。
Guideline 2-2 / CONFIDENTIAL-2: Do not log highly sensitive information
日志僅用于跟蹤業(yè)務(wù)的關(guān)鍵邏輯,方便定位問題,避免在日志記錄系統(tǒng)的關(guān)鍵數(shù)據(jù)、敏感的數(shù)據(jù)。
Guideline 2-3 / CONFIDENTIAL-3: Consider purging highly sensitive information from memory after use
對于Java語言而言,Java對象的回收由JVM控制,因此無法像使用C/C++語言時(shí)通過回收內(nèi)存的方式來清理關(guān)鍵信息。因此盡可能縮小關(guān)鍵數(shù)據(jù)、敏感數(shù)據(jù)在內(nèi)存中存在的時(shí)間窗,僅在需要的時(shí)候獲取數(shù)據(jù)。
Injection and Inclusion
Guideline 3-1 / INJECT-1: Generate valid formatting
Guideline 3-2 / INJECT-2: Avoid dynamic SQL
使用SQL訪問DB時(shí),注意對輸出參數(shù)執(zhí)行必要的轉(zhuǎn)義操作。
Guideline 9-16 / ACCESS-16: Limit package accessibility with package.access
Appendix A: Defensive use of the Java Native Interface (JNI)
JNI-1: Only use JNI when necessary
非必要的情況下,僅使用Java代碼和Java生態(tài)中的軟件來交付業(yè)務(wù)。
以個(gè)人經(jīng)歷看,這個(gè)規(guī)則可以應(yīng)付絕大多數(shù)業(yè)務(wù)交付場景,直到我參與機(jī)器學(xué)習(xí)業(yè)務(wù)之后,發(fā)現(xiàn)在這個(gè)新興的領(lǐng)域,單純依賴Java并不能獨(dú)立交付業(yè)務(wù),底層推理、訓(xùn)練的代碼依賴GPU,目前Java生態(tài)并沒有提供很好的支撐,因此需要通過JNI技術(shù)來集成相關(guān)庫和代碼,支撐業(yè)務(wù)交付工作。
JNI-2: Be aware of the C/C++ threat model
Java代碼通過JNI技術(shù)來集成本地代碼比如C/C++實(shí)現(xiàn)的特性。
Java語言在設(shè)計(jì)時(shí)限定了開發(fā)者的行為,和C/C++相比,一方面降低了開發(fā)者的自由度,另外一方面降低了對開發(fā)者的要求,避免開發(fā)者犯一些錯(cuò)誤。
開發(fā)者在開發(fā)、維護(hù)本地代碼時(shí),需要關(guān)注語言層面的差異,針對性實(shí)施必要的質(zhì)量保障措施。
JNI-3: Expect that JNI code can violate Java visibility and isolation rules
在本地代碼中可以訪問系統(tǒng)資源,比如內(nèi)存、文件、網(wǎng)絡(luò)sockets、線程、鎖、信號量等,這些資源的生命周期由開發(fā)者管理,不受Java代碼、JVM的控制。
因此在使用JNI技術(shù)時(shí),開發(fā)者需要投入額外的精力來驗(yàn)證本地代碼的質(zhì)量。
JNI-4: Secure your JNI implementation from the Java side
在Java代碼調(diào)用本地代碼時(shí),針對調(diào)用參數(shù),注意在Java代碼中增加必要的校驗(yàn),提前發(fā)現(xiàn)非法參數(shù),避免引發(fā)本地代碼中的異常表現(xiàn)。
JNI-5: Properly test JNI code for concurrent access
對于可能在多線程環(huán)境下被訪問的本地代碼,在設(shè)計(jì)、開發(fā)、測試時(shí),均應(yīng)增加必要的考慮,避免本地代碼相關(guān)的業(yè)務(wù)特性在生產(chǎn)環(huán)境變更上線后,出現(xiàn)意外的問題。
JNI-6: Secure library loading
加載JNI本地代碼的方法,如下:
System.loadLibrary("/com/foo/MyLib.so");
推薦在安全可信任的代碼中加載本地代碼,調(diào)用本地代碼中的函數(shù)。
謹(jǐn)慎使用RPATH或者RUNPATH。關(guān)閉RPATH的方法,見GCC安全編譯選項(xiàng)
GCC安全編譯選項(xiàng)。
我個(gè)人更加傾向于使用LD_LIBRARY_PATH。
JNI-7: Perform input validation at the language boundary
老生常談,在實(shí)現(xiàn)JNI函數(shù)時(shí),注意校驗(yàn)參數(shù)的有效性,避免無效數(shù)據(jù)穿越語言邊界,引發(fā)未知、未定義的行為。
JNI-8: Expect and handle exceptions when calling from JNI into Java
本地代碼不支持Java的Exception,因此在本地代碼中訪問Java的相關(guān)類和函數(shù)時(shí),假如觸發(fā)了Java的Exception,此時(shí)并不能自動改變本地代碼的運(yùn)行邏輯,Java的JNI技術(shù)提供了方法,便于開發(fā)者手工檢查是否出現(xiàn)了Exception,進(jìn)而執(zhí)行必要的恢復(fù)操作。
JNI-9: Follow secure development practices for the native target platform
基于JNI技術(shù)構(gòu)建本地庫時(shí),可以參照GCC安全編譯選項(xiàng)
GCC安全編譯選項(xiàng)
補(bǔ)齊相關(guān)選項(xiàng),借助平臺的力量,提升本地代碼的安全性。
JNI-10: Ensure that bundled JVMs and JREs meet Java's secure baselines
發(fā)布版本時(shí)攜帶JDK或者JRE,將其作為交付件的一部分,此時(shí)開發(fā)者需設(shè)計(jì)必要的更新方案,用于及時(shí)升級JDK或者JRE的版本,升級計(jì)劃與Oracle官方保持一致,及時(shí)消除潛在的安全風(fēng)險(xiǎn)。
另外,為了簡化JDK或者JRE時(shí)涉及的工作,提高升級的工作效率,因此Oracle推薦開發(fā)者應(yīng)當(dāng)避免對JDK或者JRE內(nèi)的文件進(jìn)行定制修改。
本文來自博客園,作者:jackieathome,轉(zhuǎn)載請注明原文鏈接:http://www.rzrgm.cn/jackieathome/p/18419549

浙公網(wǎng)安備 33010602011771號