內容介紹
不僅從語言角度系統而詳細地闡述java安全編碼的要素、標準、規範和最佳實踐,而且從架構設計的角度分析了java api存在的設計缺陷和可能存在的安全風險,以及應對的策略和措施。可以將本書作為java安全方面的工具書,根據自己的需要,找到自己感興趣的規則進行閱讀和理解,或者在實際開發中遇到安全問題時,根據書中列出的大致分類對規則進行索引和閱讀,也可以通讀全書的所有規則,系統地了解java安全規則,增強對java安全特性、語言使用、運行環境特性的理解。本書能指導java軟體工程師設計出高質量的、安全的、可靠的、強大的、有彈性的、可用性和可維護性高的軟體系統。
作者介紹
Fred Long 英國Aberystwyth大學計算機科學系高級講師和教學主任。主要講授形式方法、Java、C++和C的編程模式以及與編程相關的安全問題的課程。他是英國計算機協會中威爾斯分會的主席,自1992年以來在軟體工程研究所(SEI)擔任客座研究員。最近正在研究如何在Java中探查安全性漏洞。
Dhruv Mohindra 印度Persistent系統工程有限公司的高級軟體工程師。曾研發了廣泛套用於企業伺服器的監控軟體。曾在SEI的CERT項目工作,並致力於在編程社區中提高對安全問題的警覺性。曾任職於卡內基·梅隆大學,擁有信息安全策略與管理碩士學位和印度Pune大學計算機工程學士學位。
Robert C. Seacord 資深計算機安全專家和作家。在計算機安全、歷史系統改造以及基於組件的軟體工程等領域具有極深的造詣。目前管理卡內基·梅隆大學SEI的CERT在安全編碼領域的創新項目。擁有Rensselaer Polytechnic學院計算機科學學士學位。
Dean F. Sutherland CERT高級軟體安全工程師,編譯器後端技術專家組高級專家。擁有卡內基·梅隆大學博士學位。曾擔任職業軟體工程師,在Tartan公司工作超過14年。
David Svoboda CERT軟體安全工程師,資深Java開發工程師,在Java開發領域擁有13年的開發經驗。是卡內基·梅隆大學的一系列軟體開發項目的主要開發者,這些項目涉及從層級晶片建模到社會組織仿真再到自動機器學習等多個方面。
作品目錄
《java安全編碼標準》
譯者序
序
前言
致謝
第1章 概述1
1.1 錯位的信任1
1.2 注入攻擊2
1.3 敏感數據泄露3
1.4 效能泄露5
1.5 拒絕服務6
1.6 序列化8
1.7 並發性、可見性和記憶體8
1.8 最低許可權原則14
1.9 安全管理器15
1.10 類裝載器16
1.11 小結16
第2章 輸入驗證和數據淨化(ids)17
規則17
風險評估概要17
.2.1 ids00-j淨化穿越受信邊界的非受信數據18
2.2 ids01-j驗證前標準化字元串26
2.3 ids02-j在驗證之前標準化路徑名28
2.4 ids03-j不要記錄未經淨化的用戶輸入31
2.5 ids04-j限制傳遞給zipinputstream的檔案大小33
2.6 ids05-j使用ascii字元集的子集作為檔案名稱和路徑名35
2.7 ids06-j從格式字元串中排除用戶輸入37
2.8 ids07-j不要向runtime.exec()?方法傳遞非受信、未淨化的數據38
2.9 ids08-j淨化傳遞給正則表達式的非受信數據41
2.10 ds09-j如果沒有指定適當的locale,不要使用locale相關方法處理與locale相關的數據44
2.11 ids10-j不要拆分兩種數據結構中的字元串45
2.12 ids11-j在驗證前去掉非字元碼點50
2.13 ids12-j在不同的字元編碼中無損轉換字元串數據51
2.14 ids13-j在檔案或者網路i/o兩端使用兼容的編碼方式53
第3章 聲明和初始化(dcl)56
規則56
風險評估概要56
3.1 dcl00-j防止類的循環初始化56
3.2 dcl01-j不要重用java標準庫的已經公開的標識59
3.3 dcl02-j將所有增強for語句的循環變數聲明為final類型60
第4章 表達式(exp)63
規則63
風險評估概要63
4.1 exp00-j不要忽略方法的返回值63
4.2 exp01-j不要解引用空指針65
4.3 exp02-j使用兩個參數的arrays.equals()方法來比較兩個數組的內容67
4.4 exp03-j不要用相等操作符來比較兩個基礎數據類型的值67
4.5 exp04-j確保使用正確的類型來自動封裝數值72
4.6 exp05-j不要在一個表達式中對同一變數進行多次寫入73
4.7 exp06-j不要在斷言中使用有副作用的表達式76
第5章 數值類型與運算(num)78
規則78
風險評估概要78
5.1 num00-j檢測和避免整數溢出79
5.2 num01-j不要對同一數據進行位運算和數學運算85
5.3 num02-j確保除法運算和模運算中的除數不為088
5.4 num03-j使用可容納無符號數據合法取值範圍的整數類型89
5.5 num04-j不要使用浮點數進行精細計算90
5.6 num05-j不要使用非標準化數92
5.7 num06-j使用strictfp修飾符確保跨平台浮點運算的一致性94
5.8 num07-j不要嘗試與nan進行比較97
5.9 num08-j檢查浮點輸入特殊的數值98
5.10 num09-j不要使用浮點變數作為循環計數器100
5.11 num10-j不要從浮點字元構造bigdecimal對象101
5.12 num11-j不要比較或者審查以字元串表達的浮點數值102
5.13 num12-j確保將數值轉換成較小類型時不會產生數據丟失或曲解103
5.14 num13-j轉換基本整數類型至浮點類型時應避免精度損失107
第6章 面向對象(obj)110
規則110
風險評估概要110
6.1 obj00-j只有受信子類能對具有不變性的類和方法進行擴展111
6.2 obj01-j聲明數據成員為私有並提供可訪問的封裝器方法116
6.3 obj02-j當改變基類時,保存子類之間的依賴關係118
6.4 obj03-j在新代碼中,不要混用具有泛型和非泛型的原始數據類型124
6.5 obj04-j為可變類提供複製功能,並通過此功能允許將實例傳遞給非受信代碼128
6.6 obj05-j在返回引用之前,防禦性複製私有的可變的類成員132
6.7 obj06-j對可變輸入和可變的內部組件創建防禦性複製136
6.8 obj07-j不允許敏感類複製其自身138
6.9 obj08-j不要在嵌套類中暴露外部類的私有欄位141
6.10 obj09-j比較類而不是類名稱143
6.11 obj10-j不要使用公有靜態的非final變數144
6.12 obj11-j小心處理構造函式拋出異常的情況146
第7章 方法(met)153
規則153
風險評估概要153
7.1 met00-j驗證方法參數154
7.2 met01-j不要使用斷言驗證方法參數156
7.3 met02-j不要使用棄用的或過時的類和方法157
7.4 met03-j進行安全檢測的方法必須聲明為private或final158
7.5 met04-j不要增加被覆寫方法和被隱藏方法的可訪問性160
7.6 met05-j確保構造函式不會調用可覆寫的方法161
7.7 met06-j不要在clone()中調用可覆寫的方法163
7.8 met07-j不要定義類方法來隱藏基類或基類接口中聲明的方法165
7.9 met08-j確保比較等同的對象能得到相等的結果167
7.10 met09-j定義了equlas()方法的類必須定義hashcode()方法174
7.11 met10-j實現compareto()方法時遵守常規契約176
7.12 met11-j確保比較中的關鍵碼是不可變的178
7.13 met12-j不要使用析構函式182
第8章 異常行為(err)187
規則187
風險評估概要187
8.1 err00-j不要消除或忽略可檢查的異常187
8.2 err01-j不能允許異常泄露敏感信息192
8.3 err02-j記錄日誌時應避免異常196
8.4 err03-j在方法失敗時恢復對象先前的狀態197
8.5 err04-j不要在finally程式段非正常退出201
8.6 err05-j不要在finally程式段中遺漏可檢查異常202
8.7 err06-j不要拋出未聲明的可檢查異常205
8.8 err07-j不要拋出runtimeexception、exception或throwable209
8.9 err08-j不要捕捉nullpointerexception或任何它的基類210
8.10 err09-j禁止非受信代碼終止jvm216
第9章 可見性和原子性(vna)219
規則219
風險評估概要219
9.1 vna00-j當需要讀取共享基礎數據類型變數時,需要保證其可見性219
9.2 vna01-j保證對一個不可變對象的共享引用的可見性222
9.3 vna02-j保證對於共享變數的組合操作是原子性的225
9.4 vna03-j即使每一個方法都是相互獨立並且是原子性的,也不要假設一組調用是原子性的230
9.5 vna04-j保證串聯在一起的方法調用是原子性的235
9.6 vna05-j保證在讀寫64位的數值時的原子性239
第10章 鎖(lck)241
規則241
風險評估概要241
10.1 lck00-j通過私有final鎖對象可以同步那些與非受信代碼互動的類242
10.2 lck01-j不要基於那些可能被重用的對象進行同步246
10.3 lck02-j不要基於那些通過getclass()返回的類對象來實現同步249
10.4 lck03-j不要基於高層並發對象的內置鎖來實現同步252
10.5 lck04-j即使集合是可訪問的,也不要基於集合視圖使用同步253
10.6 lck05-j對那些可以被非受信代碼修改的靜態欄位,需要同步進入255
10.7 lck06-j不要使用一個實例鎖來保護共享靜態數據256
10.8 lck07-j使用相同的方式請求和釋放鎖來避免死鎖258
10.9 lck08-j在異常條件時,保證釋放已經持有的鎖266
10.10 lck09-j不要執行那些持有鎖時會阻塞的操作270
10.11 lck10-j不要使用不正確形式的雙重鎖定檢查慣用法273
10.12 lck11-j當使用那些不能對鎖策略進行承諾的類時,避免使用客戶端鎖定277
第11章 執行緒api(thi)282
規則282
風險評估概要282
11.1 thi00-j不要調用thread.run()282
11.2 thi01-j不能調用threadgroup方法284
11.3 thi02-j通知所有等待中的執行緒而不是單一執行緒287
11.4 thi03-j始終在循環中調用wait()和await()方法292
11.5 thi04-j確保可以終止受阻執行緒295
11.6 thi05-j不要使用thread.stop()來終止執行緒300
第12章 執行緒池(tps)304
規則304
風險評估概要304
12.1 tps00-j使用執行緒池處理流量突發以實現降低性能運行304
12.2 tps01-j不要使用有限的執行緒池來執行相互依賴的任務307
12.3 tps02-j確保提交至執行緒池的任務是可中斷的312
12.4 tps03-j確保執行緒池中正在執行的任務不會失敗而不給出任何提示315
12.5 tps04-j使用執行緒池時,確保threadlocal變數可以重新初始化318
第13章 與執行緒安全相關的其他規則(tsm)323
規則323
風險評估概要323
13.1 tsm00-j不要使用非執行緒安全方法來覆寫執行緒安全方法323
13.2 tsm01-j不要讓this引用在創建對象時泄漏326
13.3 tsm02-j不要在初始化類時使用後台執行緒332
13.4 tsm03-j不要發布部分初始化的對象336
第14章 輸入輸出(fio)342
規則342
風險評估概要342
14.1 fio00-j不要操作已分享資料夾中的檔案343
14.2 fio01-j使用合適的訪問許可權創建檔案351
14.3 fio02-j發現並處理與檔案相關的錯誤352
14.4 fio03-j在終止前移除臨時檔案354
14.5 fio04-j在不需要時關閉資源357
14.6 fio05-j不要使用wrap()或duplicate()創建快取,並將這些快取暴露給非受信代碼361
14.7 fio06-j不能在一個單獨的inputstream上創建多個快取區封裝器364
14.8 fio07-j不要讓外部進程阻塞輸入和輸出流367
14.9 fio08-j對讀取一個字元或者位元組的方法,使用int類型的返回值370
14.10 fio09-j不要使用write()方法輸出超過0~255的整數372
14.11 fio10-j使用read()方法保證填充一個數組373
14.12 fio11-j不要將原始的二進制數據作為字元數據讀入375
14.13 fio12-j為小端數據的讀寫提供方法376
14.14 fio13-j不要在受信邊界之外記錄敏感信息379
14.15 fio14-j在程式終止時執行正確的清理動作381
第15章 序列化(ser)387
規則387
風險評估概要387
15.1 ser00-j在類的演化過程中維護其序列化的兼容性388
15.2 ser01-j不要偏離序列化方法的正確簽名390
15.3 ser02-j在將對象向信任邊界之外傳送時,需要簽名並且封裝敏感對象392
15.4 ser03-j不要序列化未經加密的敏感數據397
15.5 ser04-j不要允許序列化和反序列化繞過安全管理器401
15.6 ser05-j不要序列化內部類實例404
15.7 ser06-j在反序列化時,對私有的可變的組件進行防禦性複製405
15.8 ser07-j不要對實現定義的不可變因素使用默認的序列化格式406
15.9 ser08-j在從擁有特性的環境中進行反序列化之前最小化特權410
15.10 ser09-j不要從readobject()方法中調用可以被覆寫的方法413
15.11 ser10-j在序列化時,避免出現記憶體和資源泄漏414
15.12 ser11-j防止覆蓋外部化的對象415
第16章 平台安全性(sec)417
規則417
風險評估概要417
16.1 sec00-j不要允許特權代碼塊越過受信邊界泄露敏感信息417
16.2 sec01-j不要在特權代碼塊中使用污染過的變數420
16.3 sec02-j不要基於非受信源進行安全檢查422
16.4 sec03-j不要在允許非受信代碼裝載任意類之後裝載受信類424
16.5 sec04-j使用安全管理器檢查來保護敏感操作426
16.6 sec05-j不要使用反射來增加類、方法和欄位的可訪問性429
16.7 sec06-j不要依賴於默認的由urlclassloader和java.util.jar提供的自動化簽名檢查434
16.8 sec07-j當編寫一個自定義的類裝載器時調用基類的getpermissions()方法437
16.9 sec08-j定義基於原生方法的封裝器438
第17章 運行環境(env)441
規則441
風險評估概要441
17.1 env00-j不要簽名只執行非特權操作的代碼441
17.2 env01-j將所有安全敏感的代碼置於單獨一個jar包中,並且在簽名之後封裝它443
17.3 env02-j不要信任環境變數的值446
17.4 env03-j不要賦予危險的許可權組合448
17.5 env04-j不要關閉位元組碼驗證功能451
17.6 env05-j不要部署一個被遠程監視的套用452
第18章 其他(msc)457
規則457
風險評估概要457
18.1 msc00-j在交換安全數據時使用sslsocket而不是socket457
18.2 msc01-j不要使用空的無限循環461
18.3 msc02-j生成強隨機數462
18.4 msc03-j不要硬編碼敏感信息464
18.5 msc04-j防止記憶體泄漏466
18.6 msc05-j不要耗盡堆空間473
18.7 msc06-j當一個遍歷正在進行時,不要修改它對應的集合477
18.8 msc07-j防止多次實例化單例對象481
術語表490
參考資源497