版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、(安全生產(chǎn))J編寫過程中 安全問題解決指南20XX年XX月多年的企業(yè)咨詢豉問經(jīng)驗.經(jīng)過實戰(zhàn)驗證可以落地機行的卓越管理方案,值得您下載擁有在本文中,我們討論了對付13 種不同靜態(tài)暴露的技巧。對于每種暴露,我們解釋了不處理這些安全性問題所造成的影響。我們?nèi)詾槟扑]了壹些準則,要開發(fā)不受這些靜態(tài)安全性暴露威脅的、健壯且安全的 Java 應用程序,您應該遵循這些準則。壹有合適的時機,我們就提供代碼樣本(既有暴露的代碼也有無暴露的代碼) 。對付高嚴重性暴露的技巧請遵循下列建議以避免高嚴重性靜態(tài)安全性暴露:限制對變量的訪問讓每個類和方法都成為 final ,除非有足夠的理由不這樣做不要依賴包作用域使類不可
2、克隆使類不可序列化使類不可逆序列化避免硬編碼敏感數(shù)據(jù)查找惡意代碼限制對變量的訪問如果將變量聲明為 public ,那么外部代碼就能夠操作該變量。這可能會導致安全性暴露。影響如果實例變量為 public ,那么就能夠在類實例上直接訪問和操作該實例變量。將實例變量聲明為 protected 且不壹定能解決這壹問題: 雖然不可能直接在類實例基礎上訪問這樣的變量,但仍然能夠從派生類訪問這個變量。清單1 演示了帶有public 變量的代碼,因為變量為public 的,所以它暴露了。清單1. 帶有public 變量的代碼classTest publicintid;protectedStringname;T
3、est()id=1;name=helloworld;/codepublicclassMyClassextendsTestpublicvoidmethodIllegalSet(Stringname)=name;/thisshouldnotbeallowedpublicstaticvoidmain(Stringargs)Testobj=newTest();obj.id=123;/thisshouldnotbeallowedMyClassmc=newMyClass();mc.methodIllegalSet(IllegalSetValue);建議壹般來說, 應該使用取值方法而不是p
4、ublic 變量。 按照具體問題具體對待的原則, 在確定哪些變量特別重要因而應該聲明為 private 時,請將編碼的方便程度及成本同安全性需要加以比較。清單2 演示了以下列方式來使之安全的代碼:清單 2. 不帶有 public 變量的代碼classTestprivateintid;privateStringname;Test()id=1;name=helloworld;publicvoidsetId(intid)this.id=id;publicvoidsetName(Stringname) =name;publicintgetId()returnid;publicStri
5、nggetName() returnname;讓每個類和方法都為 final不允許擴展的類和方法應該聲明為 final 。這樣做防止了系統(tǒng)外的代碼擴展類且修改類的行為。影響僅僅將類聲明為非public 且不能防止攻擊者擴展類,因為仍然能夠從它自己的包內(nèi)訪問該類。建議讓每個類和方法都成為 final , 除非有足夠的理由不這樣做。 按此建議, 我們要求您放棄可擴展性,雖然它是使用諸如 Java 語言之類的面向對象語言的主要優(yōu)點之壹。在試圖提供安全性時,可擴展性卻成了您的敵人;可擴展性只會為攻擊者提供更多給您帶來麻煩的方法。不要依賴包作用域沒有顯式地標注為 public 、 private 或 p
6、rotected 的類、方法和變量在它們自己的包內(nèi)是可訪問的。影響如果 Java 包不是封閉的,那么攻擊者就能夠向包內(nèi)引入新類且使用該新類來訪問您想保護的內(nèi)容。 諸如 java.lang 之類的壹些包缺省是封閉的, 壹些 JVM 也讓您封閉自己的包。 然而,您最好假定包是不封閉的。建議從軟件工程觀點來見,包作用域具有重要意義,因為它能夠阻止對您想隱藏的內(nèi)容進行偶然的、 無意中的訪問。 但不要依靠它來獲取安全性。 應該將類、 方法和變量顯式標注為 public 、private 或 protected 中適合您特定需求的那種。使類不可克隆 克隆允許繞過構造器而輕易地復制類實例。影響 即使您沒有有
7、意使類可克隆,外部源仍然 能夠定義您的類的子類,且使該子類實現(xiàn)java.lang.Cloneable 。 這就讓攻擊者創(chuàng)建了您的類的新實例。 拷貝現(xiàn)有對象的內(nèi)存映象生成了新的實例; 雖然這樣做有時候是生成新對象的可接受方法, 可是大多數(shù)時候是不可接受的。清單3 說明了因為可克隆而暴露的代碼:清單3. 可克隆代碼classMyClassprivateintid;privateStringname;publicMyClass()id=1;name=HaryPorter;publicMyClass(intid,Stringname)this.id=id;=name;publicvo
8、iddisplay()System.out.println(Id=+id+Name=+name);/hackerscodetoclonetheuserclass publicclassHackerextendsMyClassimplementsCloneablepublicstaticvoidmain(Stringargs)Hackerhack=newHacker();tryMyClasso=(MyClass)hack.clone();o.display();catch(CloneNotSupportedExceptione)e.printStackTrace();建議要防止類被克隆,能夠將清
9、單4 中所示的方法添加到您的類中:清單 4. 使您的代碼不可克隆publicfinalObjectclone()throwsjava.lang.CloneNotSupportedExceptionthrownewjava.lang.CloneNotSupportedException();如果想讓您的類可克隆且且您已經(jīng)考慮了這壹選擇的后果,那么您仍然能夠保護您的類。要做到這壹點,請在您的類中定義壹個為 final 的克隆方法,且讓它依賴于您的壹個超類中的壹個非 final 克隆方法,如清單5 中所示:清單 5. 以安全的方式使您的代碼可克隆publicfinalObjectclone()thr
10、owsjava.lang.CloneNotSupportedExceptionsuper.clone();類中出現(xiàn) clone() 方法防止攻擊者重新定義您的 clone 方法。使類不可序列化序列化允許將類實例中的數(shù)據(jù)保存在外部文件中。闖入代碼能夠克隆或復制實例,然后對它進行序列化。影響序列化是令人擔憂的,因為它允許外部源獲取對您的對象的內(nèi)部狀態(tài)的控制。這壹外部源能夠將您的對象之壹序列化成攻擊者隨后能夠讀取的字節(jié)數(shù)組,這使得攻擊者能夠完全審查您的對象的內(nèi)部狀態(tài),包括您標記為 private 的任何字段。它也允許攻擊者訪問您引用的任何對象的內(nèi)部狀態(tài)。建議要防止類中的對象被序列化,請在類中定義清單
11、6 中的 writeObject() 方法:清單 6. 防止對象序列化privatefinalvoidwriteObject(ObjectOutputStreamout)throwsjava.io.NotSerializableExceptionthrownewjava.io.NotSerializableException(Thisobjectcannot beserialized);通過將 writeObject() 方法聲明為final ,防止了攻擊者覆蓋該方法。使類不可逆序列化通過使用逆序列化,攻擊者能夠用外部數(shù)據(jù)或字節(jié)流來實例化類。影響不管類是否能夠序列化,都能夠對它進行逆序列化。外
12、部源能夠創(chuàng)建逆序列化成類實例的字節(jié)序列。這種可能為您帶來了大量風險,因為您不能控制逆序列化對象的狀態(tài)。請將逆序列化作為您的對象的另壹種公共構造器?壹種您無法控制的構造器。建議要防止對對象的逆序列化,應該在您的類中定義清單7 中的 readObject() 方法:清單7. 防止對象逆序列化privatefinalvoidreadObject(ObjectInputStreamin)throwsjava.io.NotSerializableExceptionthrownewjava.io.NotSerializableException(Thisobjectcannotbedeserialized
13、);通過將該方法聲明為 final ,防止了攻擊者覆蓋該方法。避免硬編碼敏感數(shù)據(jù)您可能會嘗試將諸如加密密鑰之類的秘密存放在您的應用程序或庫的代碼。對于你們開發(fā)人員來說,這樣做通常會把事情變得更簡單。影響 任何運行您的代碼的人都能夠完全訪問以這種方法存儲的秘密。沒有什么東西能夠防止心懷 叵測的程序員或虛擬機窺探您的代碼且了解其秘密。建議能夠以壹種只可被您解密的方式將秘密存儲在您代碼中。在這種情形下,秘密只在于您的代碼所使用的算法。這樣做沒有多大壞處,但不要洋洋得意,認為這樣做提供了牢固的保護。您能夠遮掩您的源代碼或字節(jié)碼?也就是,以壹種為了解密必須知道加密格式的方法對源代碼或字節(jié)碼進行加密?但攻
14、擊者極有可能能夠推斷出加密格式,對遮掩的代碼進行逆向工程從而揭露其秘密。這壹問題的壹種可能解決方案是:將敏感數(shù)據(jù)保存在屬性文件中,無論什么時候需要這些數(shù)據(jù),都能夠從該文件讀取。如果數(shù)據(jù)極其敏感,那么在訪問屬性文件時,您的應用程序應該使用壹些加密解密技術。查找惡意代碼從事某個項目的某個心懷叵測的開發(fā)人員可能故意引入易受攻擊的代碼,打算日后利用它。這樣的代碼在初始化時可能會啟動壹個后臺進程,該進程能夠為闖入者開后門。它也能夠更改壹些敏感數(shù)據(jù)。這樣的惡意代碼有三類:類中的 main 方法定義過且未使用的方法注釋中的死代碼影響入口點程序可能很危險而且有惡意。通常, Java 開發(fā)人員往往在其類中編寫
15、main() 方法,這有助于測試單個類的功能。 當類從測試轉移到生產(chǎn)環(huán)境時, 帶有 main() 方法的類就成為了對應用程序的潛在威脅,因為闖入者將它們用作入口點。請檢查代碼中是否有未使用的方法出現(xiàn)。這些方法在測試期間將會通過所有的安全檢查,因為在代碼中不調用它們?但它們可能含有硬編碼在它們內(nèi)部的敏感數(shù)據(jù)(雖然是測試數(shù)據(jù))引入壹小段代碼的攻擊者隨后可能調用這樣的方法。避免最終應用程序中的死代碼(注釋內(nèi)的代碼) 。如果闖入者去掉了對這樣的代碼的注釋,那么代碼可能會影響系統(tǒng)的功能性。能夠在清單8 中見到所有三種類型的惡意代碼的示例:清單 8. 潛在惡意的 Java 代碼publicvoidunus
16、edMethod()/codewrittentoharmthesystempublicvoidusedMethod()/unusedMethod();/codeincommentputwithbadintentions,/mightaffectthesystemifuncommented/intx=100;/x=x+10;/Codeincomment,mightaffectthe/functionalityofthesystemifuncommented建議應該將 (除啟動應用程序的 main() 方法之外的) main() 方法、 未使用的方法以及死代碼從應用程序代碼中除去。在軟件交付使用之
17、前,主要開發(fā)人員應該對敏感應用程序進行壹次全面的代碼評審。應該使用“ Stub ”或“ dummy ”類代替 main() 方法以測試應用程序的功能。對付中等嚴重性暴露的技巧請遵循下列建議以避免中等嚴重性靜態(tài)安全性暴露:不要依賴初始化不要通過名稱來比較類不要使用內(nèi)部類不要依賴初始化您能夠不運行構造器而分配對象。這些對象使用起來不安全,因為它們不是通過構造器初始化的。影響在初始化時驗證對象確保了數(shù)據(jù)的完整性。例如,請想象為客戶創(chuàng)建新帳戶的 Account 對象。只有在Account 期初余額大于0 時,才能夠開設新帳戶。能夠在構造器里執(zhí)行這樣的驗證。有些人未執(zhí)行構造器而創(chuàng)建Account對象,他
18、可能創(chuàng)建了壹個具有壹些負值的新帳戶,這樣會使系統(tǒng)不壹致,容易受到進壹步的干預。建議在使用對象之前,請檢查對象的初始化過程。要做到這壹點,每個類都應該有壹個在構造器中設置的私有布爾標志,如清單9 中的類所示。在每個非static 方法中,代碼在任何進壹步執(zhí)行之前都應該檢查該標志的值。 如果該標志的值為 true , 那么控制應該進壹步繼續(xù); 否則,控制應該拋出壹個例外且停止執(zhí)行。那些從構造器調用的方法將不會檢查初始化的變量,因為在調用方法時沒有設置標志。 因為這些方法且不檢查標志, 所以應該將它們聲明為private以防止用戶直接訪問它們。清單 9. 使用布爾標志以檢查初始化過程publiccl
19、assMyClassprivatebooleaninitialized=false;/OthervariablespublicMyClass()/variableinitializationmethod1();initialized=true;privatevoidmethod1()/noneedtocheckforinitializationvariable/codepublicvoidmethod2()tryif(initialized=true)/proceedwiththebusinesslogicelsethrownewException(IllegalStateOftheobjec
20、t);catch(Exceptione)e.printStackTrace();如果對象由逆序列化進行初始化,那么上面討論的驗證機制將難以奏效,因為在該過程中且不調用構造器。在這種情況下,類應該實現(xiàn)ObjectInputValidation 接口:清單 10. 實現(xiàn) ObjectInputValidationinterfacejava.io.ObjectInputValidationpublicvoidvalidateObject()throwsInvalidObjectException;所 有 驗 證 都 應 該 在 validateObject() 方 法 中 執(zhí) 行 。 對 象 仍 必
21、 須 調 用ObjectInputStream.RegisterValidation() 方法以為逆序列化對象之后的驗證進行注冊。RegisterValidation() 的第壹個參數(shù)是實現(xiàn)validateObject() 的對象, 通常是對對象自身的引用。注:任何實現(xiàn)validateObject() 的對象都可能充當對象驗證器,但對象通常驗證它自己對其它對象的引用。 RegisterValidation() 的第二個參數(shù)是壹個確定回調順序的整數(shù)優(yōu)先級,優(yōu)先級數(shù)字大的比優(yōu)先級數(shù)字小的先回調。同壹優(yōu)先級內(nèi)的回調順序則不確定。當對象已逆序列化時, ObjectInputStream按照從高到低的優(yōu)
22、先級順序調用每個已注冊對象上的validateObject() 。不要通過名稱來比較類有時候,您可能需要比較倆個對象的類,以確定它們是否相同;或者,您可能想見見某個對象是否是某個特定類的實例。因為 JVM 可能包括多個具有相同名稱的類(具有相同名稱但卻在不同包內(nèi)的類) ,所以您不應該根據(jù)名稱來比較類。影響如果根據(jù)名稱來比較類,您可能無意中將您不希望授予別人的權利授予了闖入者的類,因為闖入者能夠定義和您的類同名的類。例如,請假設您想確定某個對象是否是類com.bar.Foo 的實例。清單11 演示了完成這壹任務的錯誤方法:清單 11. 比較類的錯誤方法if(obj.getClass().getN
23、ame().equals(Foo)/Wrong!/objectsclassisnamedFooelse/objectsclasshassomeothername建議在那些非得根據(jù)名稱來比較類的情況下,您必須格外小心,必須確保使用了當前類的ClassLoader 的當前名稱空間,如清單12 中所示:清單 12. 比較類的更好方法if(obj.getClass()=this.getClassLoader().loadClass(com.bar.Foo)/objectsclassisequalto/theclassthatthisclasscallscom.bar.Fooelse/objectscl
24、assisnotequaltotheclassthat/thisclasscallscom.bar.Foo然而,比較類的更好方法是直接比較類對象見它們是否相等。例如,如果您想確定倆個對象a 和 b 是否屬同壹個類,那么您就應該使用清單13 中的代碼:清單 13. 直接比較對象來見它們是否相等if(a.getClass()=b.getClass() /objectshavethesameclasselse/objectshavedifferentclasses盡可能少用直接名稱比較。不要使用內(nèi)部類Java 字節(jié)碼沒有內(nèi)部類的概念, 因為編譯器將內(nèi)部類轉換成了普通類, 而如果沒有將內(nèi)部類聲明為 p
25、rivate ,則同壹個包內(nèi)的任何代碼恰好能訪問該普通類。影響因為有這壹特性,所以包內(nèi)的惡意代碼能夠訪問這些內(nèi)部類。如果內(nèi)部類能夠訪問括起外部類的字段,那么情況會變得更糟??赡芤呀?jīng)將這些字段聲明為 private ,這樣內(nèi)部類就被轉換成了獨立類,但當內(nèi)部類訪問外部類的字段時,編譯器就將這些字段從專用( private )的變?yōu)樵诎? package )的作用域內(nèi)有效的。內(nèi)部類暴露了已經(jīng)夠糟糕的了,但更糟糕的是編譯器使您將某些字段成為 private 的舉動成為徒勞。建議如果能夠不使用內(nèi)部類就不要使用內(nèi)部類。對付低嚴重性暴露的技巧請遵循下列建議以避免低嚴重性靜態(tài)安全性暴露:避免返回可變對象檢查本
26、機方法避免返回可變對象Java 方法返回對象引用的副本。 如果實際對象是可改變的, 那么使用這樣壹個引用調用程序可能會改變它的內(nèi)容,通常這是我們所不希望見到的。影響請考慮這個示例:某個方法返回壹個對敏感對象的內(nèi)部數(shù)組的引用,假定該方法的調用程序不改變這些對象。 即使數(shù)組對象本身是不可改變的, 也能夠在數(shù)組對象以外操作數(shù)組的內(nèi)容,這種操作將反映在返回該數(shù)組的對象中。如果該方法返回可改變的對象,那么事情會變得更糟;外部實體能夠改變在那個類中聲明的 public 變量,這種改變將反映在實際對象中。清單 14 演示了脆弱性。 getExposedObj() 方法返回了 Exposed 對象的引用副本,
27、該對象是可變的:清單 14. 返回可變對象的引用副本classExposedprivateintid;privateStringname;publicExposed()publicExposed(intid,Stringname)this.id=id;=name;publicintgetId()returnid; publicStringgetName()returnname;publicvoidsetId(intid)this.id=id;publicvoidsetName(Stringname)=name;publicvoiddisplay()Syste
28、m.out.println(Id=+id+Name=+name);publicclassExp12privateExposedexposedObj=newExposed(1,HarryPorter);publicExposedgetExposedObj()returnexposedObj;/returnsareferencetotheobject.publicstaticvoidmain(Stringargs)Exp12exp12=newExp12();exp12.getExposedObj().display();Exposedexposed=exp12.getExposedObj();ex
29、posed.setId(10);exposed.setName(Hacker);exp12.getExposedObj().display();建議如果方法返回可改變的對象,但又不希望調用程序改變該對象,請修改該方法使之不返回實際對象而是返回它的副本或克隆。要改正清單14 中的代碼,請讓它返回 Exposed 對象的副本 ,如清單 15 中所示:清單 15. 返回可變對象的副本publicExposedgetExposedObj()returnnewExposed(exposedObj.getId(),exposedObj.getName();或者,您的代碼也能夠返回 Exposed 對象的克
30、隆。檢查本機方法本機方法是壹種 Java 方法,其實現(xiàn)是用另壹種編程語言編寫的,如 C 或 C+ 。有些開發(fā)人員實現(xiàn)本機方法,這是因為 Java 語言即使使用即時( just-in-time )編譯器也比許多編譯過的語言要慢。其它人需要使用本機代碼是為了在JVM 以外實現(xiàn)特定于平臺的功能。影響使用本機代碼時,請小心,因為對這些代碼進行驗證是不可能的,而且本機代碼可能潛在地允許 applet 繞過通常的安全性管理器( SecurityManager )和 Java 對設備訪問的控制。建議 如果非得使用本機方法,那么請檢查這些方法以確定:它們返回什么 它們獲取什么作為參數(shù)它們是否繞過安全性檢查它們是否是public 、 private 等等它們是否含有繞過包邊界從而繞過包保護
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度美容院員工社會保險繳納合同樣本4篇
- 課題申報參考:面向2035年高等教育布局結構研究
- 民政局2025年離婚協(xié)議書起草與備案流程指導4篇
- 2025年度門頭房屋租賃合同含租賃用途及經(jīng)營方向限制4篇
- 河南省周口中英文學校高三上學期期中考試語文試題(含答案)
- 2025年度個人二手房交易反擔保合同規(guī)范2篇
- 2025年度個人汽車貨運風險分擔合同范本
- 2025年度門禁監(jiān)控設備生產(chǎn)與銷售合同8篇
- 2025年度水電工程合同履約監(jiān)管承包協(xié)議4篇
- 2025年度木結構建筑綠色施工與環(huán)保驗收合同4篇
- 喬遷新居結婚典禮主持詞
- 小學四年級數(shù)學競賽試題(附答案)
- 魯科版高中化學必修2全冊教案
- 人口分布 高一地理下學期人教版 必修第二冊
- 子宮內(nèi)膜異位癥診療指南
- 教案:第三章 公共管理職能(《公共管理學》課程)
- 諾和關懷俱樂部對外介紹
- 玩轉數(shù)和形課件
- 保定市縣級地圖PPT可編輯矢量行政區(qū)劃(河北省)
- 新蘇教版科學六年級下冊全冊教案(含反思)
- 天然飲用山泉水項目投資規(guī)劃建設方案
評論
0/150
提交評論