安全編碼規(guī)范_第1頁
安全編碼規(guī)范_第2頁
安全編碼規(guī)范_第3頁
安全編碼規(guī)范_第4頁
安全編碼規(guī)范_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

安全編碼規(guī)范版本號:V1.0

修訂頁編號章節(jié)名稱修訂內(nèi)容簡述修訂日期修訂前版本號修訂后版本號修訂人批準(zhǔn)人

目錄1 目的 52 背景 53 安全編碼規(guī)范 53.1 輸入驗證和數(shù)據(jù)合法性校驗 53.1.1 避免SQL注入 53.1.2 避免XML注入 53.1.3 避免跨站點腳本(XSS) 63.2 聲明和初始化 63.2.1 避免類初始化的相互依賴 63.3 表達(dá)式 73.3.1 不可忽略方法的返回值 73.3.2 不要引用空指針 83.3.3 使用Arrays.equals()來比較數(shù)組的內(nèi)容 83.4 數(shù)字類型和操作 83.4.1 防止整數(shù)溢出 83.4.2 避免除法和取模運算分母為零 93.5 類和方法操作 103.5.1 數(shù)據(jù)成員聲明為私有,提供可訪問的包裝方法 103.5.2 敏感類不允許復(fù)制 103.5.3 比較類的正確做法 103.5.4 不要硬編碼敏感信息 113.5.5 驗證方法參數(shù) 113.5.6 不要使用過時、陳舊或低效的方法 113.5.7 數(shù)組引用問題 113.5.8 不要產(chǎn)生內(nèi)存泄露 123.6 異常處理 123.6.1 不要忽略捕獲的異常 123.6.2 不允許暴露異常的敏感信息 133.6.3 不允許拋出RuntimeException,Exception,Throwable 143.6.4 不要捕獲NullPointerException或其他父類異常 143.7 多線程編程 153.7.1 確保共享變量的可見性 153.7.2 確保共享變量的操作是原子的 163.7.3 不要調(diào)用Thread.run(),不要使用Thread.stop()以終止線程 183.7.4 確保執(zhí)行阻塞操作的線程可以終止 183.7.5 相互依存的任務(wù)不要在一個有限的線程池執(zhí)行 193.8 輸入輸出 193.8.1 程序終止前刪除臨時文件 193.8.2 檢測和處理文件相關(guān)的錯誤 193.8.3 及時釋放資源 193.9 序列化 203.9.1 不要序列化未加密的敏感數(shù)據(jù) 203.9.2 在序列化過程中避免內(nèi)存和資源泄漏 213.9.3 反序列化要在程序最小權(quán)限的安全環(huán)境中 22安全編碼規(guī)范輸入驗證和數(shù)據(jù)合法性校驗程序接受數(shù)據(jù)也許來源于未經(jīng)驗證的用戶,網(wǎng)絡(luò)連接和其他不受信任的來源,假如未對程序接受數(shù)據(jù)進(jìn)行校驗,則也許會引發(fā)安全問題。避免SQL注入使用PreparedStatement預(yù)編譯SQL,解決SQL注入問題,傳遞給PreparedStatement對象的參數(shù)可以被強制進(jìn)行類型轉(zhuǎn)換,保證在插入或查詢數(shù)據(jù)時與底層的數(shù)據(jù)庫格式匹配。

StringsqlString="select*fromdb_userwhereusername=?andpassword=?";PreparedStatementstmt=connection.prepareStatement(sqlString);stmt.setString(1,username);stmt.setString(2,pwd);ResultSetrs=stmt.executeQuery();避免XML注入通過StringBulider或StringBuffer拼接XML文獻(xiàn)時,需對輸入數(shù)據(jù)進(jìn)行合法性校驗。對數(shù)量quantity進(jìn)行合法性校驗,控制只能傳入0-9的數(shù)字:if(!Pattern.matches("[0-9]+",quantity)){//Formatviolation}StringxmlString="<item>\n<description>Widget</description>\n"+"<price>500</price>\n"+"<quantity>"+quantity+"</quantity></item>";outStream.write(xmlString.getBytes());outStream.flush();避免跨站點腳本(XSS)對產(chǎn)生跨站的參數(shù)進(jìn)行嚴(yán)格過濾,嚴(yán)禁傳入<SCRIPT>標(biāo)簽//定義需過濾的字段串<script>Strings="\uFE64"+"script"+"\uFE65";//過濾字符串標(biāo)準(zhǔn)化s=Normalizer.normalize(s,Form.NFKC);//使用正則表達(dá)式匹配inputStr是否存在<script>Patternpattern=Ppile(inputStr);Matchermatcher=pattern.matcher(s);if(matcher.find()){//FoundblacklistedtagthrownewIllegalStateException();}else{//...}聲明和初始化避免類初始化的互相依賴?yán)哄e誤的寫法:publicclassCycle{privatefinalintbalance;privatestaticfinalCyclec=newCycle();privatestaticfinalintdeposit=(int)(Math.random()*100);//RandomdepositpublicCycle(){balance=deposit-10;//Subtractprocessingfee}publicstaticvoidmain(String[]args){System.out.println("Theaccountbalanceis:"+c.balance);}}類加載時初始化指向Cycle類的靜態(tài)變量c,而類Cycle的無參構(gòu)造方法又依賴靜態(tài)變量deposit,導(dǎo)致無法預(yù)期的結(jié)果。對的的寫法:publicclassCycle{privatefinalintbalance;privatestaticfinalintdeposit=(int)(Math.random()*100);//RandomdepositprivatestaticfinalCyclec=newCycle();//InsertedafterinitializationofrequiredfieldspublicCycle(){balance=deposit-10;//Subtractprocessingfee}publicstaticvoidmain(String[]args){System.out.println("Theaccountbalanceis:"+c.balance);}}表達(dá)式不可忽略方法的返回值忽略方法的放回值也許會導(dǎo)致無法預(yù)料的結(jié)果。錯誤的寫法:publicvoiddeleteFile(){FilesomeFile=newFile("someFileName.txt");someFile.delete();}對的的寫法:publicvoiddeleteFile(){FilesomeFile=newFile("someFileName.txt");if(!someFile.delete()){//handlefailuretodeletethefile}}不要引用空指針當(dāng)一個變量指向一個NULL值,使用這個變量的時候又沒有檢查,這時會導(dǎo)致。NullPointerException。在使用變量前一定要做是否為NULL值的校驗。使用Arrays.equals()來比較數(shù)組的內(nèi)容數(shù)組沒有覆蓋的Object.equals()方法,調(diào)用Object.equals()方法事實上是比較數(shù)組的引用,而不是他們的內(nèi)容。程序必須使用兩個參數(shù)Arrays.equals()方法來比較兩個數(shù)組的內(nèi)容publicvoidarrayEqualsExample(){int[]arr1=newint[20];//initializedto0int[]arr2=newint[20];//initializedto0Arrays.equals(arr1,arr2);//true}數(shù)字類型和操作防止整數(shù)溢出使用\o"java.lang中的類"java.lang.Number.BigInteger類進(jìn)行整數(shù)運算,防止整數(shù)溢出。publicclassBigIntegerUtil{privatestaticfinalBigIntegerbigMaxInt=BigInteger.valueOf(Integer.MAX_VALUE);privatestaticfinalBigIntegerbigMinInt=BigInteger.valueOf(Integer.MIN_VALUE);publicstaticBigIntegerintRangeCheck(BigIntegerval)throwsArithmeticException{if(pareTo(bigMaxInt)==1||pareTo(bigMinInt)==-1){thrownewArithmeticException("Integeroverflow");}returnval;}publicstaticintaddInt(intv1,intv2)throwsArithmeticException{BigIntegerb1=BigInteger.valueOf(v1);BigIntegerb2=BigInteger.valueOf(v2);BigIntegerres=intRangeCheck(b1.add(b2));returnValue();}publicstaticintsubInt(intv1,intv2)throwsArithmeticException{BigIntegerb1=BigInteger.valueOf(v1);BigIntegerb2=BigInteger.valueOf(v2);BigIntegerres=intRangeCheck(b1.subtract(b2));returnValue();}publicstaticintmultiplyInt(intv1,intv2)throwsArithmeticException{BigIntegerb1=BigInteger.valueOf(v1);BigIntegerb2=BigInteger.valueOf(v2);BigIntegerres=intRangeCheck(b1.multiply(b2));returnValue();}publicstaticintdivideInt(intv1,intv2)throwsArithmeticException{BigIntegerb1=BigInteger.valueOf(v1);BigIntegerb2=BigInteger.valueOf(v2);BigIntegerres=intRangeCheck(b1.divide(b2));returnValue();}}避免去法和取模運算分母為零要避免由于分母為零而導(dǎo)致除法和取模運算出現(xiàn)異常。if(num2==0){//handleerror}else{result1=num1/num2;result2=num1%num2;}類和方法操作數(shù)據(jù)成員聲明為私有,提供可訪問的包裝方法襲擊者可以用意想不到的方式操縱public或protected的數(shù)據(jù)成員,所以需要將數(shù)據(jù)成員為private,對外提供可控的包裝方法訪問數(shù)據(jù)成員。敏感類不允許復(fù)制包含私人的,機(jī)密或其他敏感數(shù)據(jù)的類是不允許被復(fù)制的,解決的方法有兩種:類聲明為finalfinalclassSensitiveClass{//...}Clone方法拋出CloneNotSupportedException異常classSensitiveClass{//...publicfinalSensitiveClassclone()throwsCloneNotSupportedException{thrownewCloneNotSupportedException();}}比較類的對的做法假如由同一個類裝載器裝載,它們具有相同的完全限定名稱,則它們是兩個相同的類。不對的寫法://Determinewhetherobjectauthhasrequired/expectedclassobjectif(auth.getClass().getName().equals("com.application.auth.DefaultAuthenticationHandler")){//...}對的寫法://Determinewhetherobjectauthhasrequired/expectedclassnameif(auth.getClass()==com.application.auth.DefaultAuthenticationHandler.class){//...}不要硬編碼敏感信息硬編碼的敏感信息,如密碼,服務(wù)器IP地址和加密密鑰,也許會泄露給襲擊者。敏感信息均必須存在在配置文獻(xiàn)或數(shù)據(jù)庫中。驗證方法參數(shù)驗證方法的參數(shù),可保證操作方法的參數(shù)產(chǎn)生有效的結(jié)果。不驗證方法的參數(shù)也許會導(dǎo)致不對的的計算,運營時異常,違反類的不變量,對象的狀態(tài)不一致。對于跨信任邊界接受參數(shù)的方法,必須進(jìn)行參數(shù)合法性校驗privateObjectmyState=null;//對于修改myState方法的入?yún)ⅲM(jìn)行非空和合法性校驗voidsetState(Objectstate){

if(state==null){

//Handlenullstate

}

if(isInvalidState(state)){

//Handleinvalidstate

}

myState=state;}不要使用過時、陳舊或低效的方法在程序代碼中使用過時的、陳舊的或低效的類或方法也許會導(dǎo)致錯誤的行為。數(shù)組引用問題某個方法返回一個對敏感對象的內(nèi)部數(shù)組的引用,假定該方法的調(diào)用程序不改變這些對象。即使數(shù)組對象自身是不可改變的,也可以在數(shù)組對象以外操作數(shù)組的內(nèi)容,這種操作將反映在返回該數(shù)組的對象中。假如該方法返回可改變的對象,外部實體可以改變在那個類中聲明的public變量,這種改變將反映在實際對象中。不對的的寫法:publicclassXXX{ privateString[]xxxx; publicString[]getXXX(){ returnxxxx; }}對的的寫法:publicclassXXX{ privateString[]xxxx; publicString[]getXXX(){ Stringtemp[]=Arrays.copyof(…);//或其他數(shù)組復(fù)制方法 returntemp; }}不要產(chǎn)生內(nèi)存泄露垃圾收集器只收集不可達(dá)的對象,因此,存在未使用的可到達(dá)的對象,仍然表達(dá)內(nèi)存管理不善。過度的內(nèi)存泄漏也許會導(dǎo)致內(nèi)存耗盡,拒絕服務(wù)(DoS)。異常解決不要忽略捕獲的異常對于捕獲的異常要進(jìn)行相應(yīng)的解決,不能忽略已捕獲的異常不對的寫法:classFooimplementsRunnable{publicvoidrun(){try{Thread.sleep(1000);}catch(InterruptedExceptione){//此處InterruptedException被忽略}}}對的寫法:classFooimplementsRunnable{publicvoidrun(){try{Thread.sleep(1000);}catch(InterruptedExceptione){Thread.currentThread().interrupt();//Resetinterruptedstatus}}}不允許暴露異常的敏感信息沒有過濾敏感信息的異常堆棧往往會導(dǎo)致信息泄漏,不對的的寫法:try{FileInputStreamfis=newFileInputStream(System.getenv("APPDATA")+args[0]);}catch(FileNotFoundExceptione){//LogtheexceptionthrownewIOException("Unabletoretrievefile",e);}對的的寫法:classExceptionExample{publicstaticvoidmain(String[]args){Filefile=null;try{file=newFile(System.getenv("APPDATA")+args[0]).getCanonicalFile();if(!file.getPath().startsWith("c:\\homepath")){log.error("Invalidfile");return;}}catch(IOExceptionx){log.error("Invalidfile");return;}try{FileInputStreamfis=newFileInputStream(file);}catch(FileNotFoundExceptionx){log.error("Invalidfile");return;}}}不允許拋出RuntimeException,Exception,Throwable不對的的寫法:booleanisCapitalized(Strings){if(s==null){thrownewRuntimeException("NullString");}}privatevoiddoSomething()throwsException{//...}對的寫法:booleanisCapitalized(Strings){if(s==null){thrownewNullPointerException();}}privatevoiddoSomething()throwsIOException{//...}不要捕獲NullPointerException或其他父類異常不對的的寫法:booleanisName(Strings){try{Stringnames[]=s.split("");if(names.length!=2){returnfalse;}return(isCapitalized(names[0])&&isCapitalized(names[1]));}catch(NullPointerExceptione){returnfalse;}}對的的寫法:booleanisName(Strings)/*throwsNullPointerException*/{Stringnames[]=s.split("");if(names.length!=2){returnfalse;}return(isCapitalized(names[0])&&isCapitalized(names[1]));}多線程編程保證共享變量的可見性對于共享變量,要保證一個線程對它的改動對其他線程是可見的。線程也許會看到一個陳舊的共享變量的值。為了共享變量是最新的,可以將變量聲明為volatile或同步讀取和寫入操作。將共享變量聲明為volatile:finalclassControlledStopimplementsRunnable{privatevolatilebooleandone=false;@Overridepublicvoidrun(){while(!done){try{//...Thread.currentThread().sleep(1000);//Dosomething}catch(InterruptedExceptionie){Thread.currentThread().interrupt();//Resetinterruptedstatus}}}publicvoidshutdown(){done=true;}}同步讀取和寫入操作:finalclassControlledStopimplementsRunnable{privatebooleandone=false;@Overridepublicvoidrun(){while(!isDone()){try{//...Thread.currentThread().sleep(1000);//Dosomething}catch(InterruptedExceptionie){Thread.currentThread().interrupt();//Resetinterruptedstatus}}}publicsynchronizedbooleanisDone(){returndone;}publicsynchronizedvoidshutdown(){done=true;}}保證共享變量的操作是原子的除了要保證共享變量的更新對其他線程可見的,還需要保證對共享變量的操作是原子的,這時將共享變量聲明為volatile往往是不夠的。需要使用同步機(jī)制或Lock同步讀取和寫入操作:finalclassFlag{privatevolatilebooleanflag=true;publicsynchronizedvoidtoggle(){flag^=true;//Sameasflag=!flag;}publicbooleangetFlag(){returnflag;}}//使用讀取鎖保證讀取和寫入操作的原子性finalclassFlag{privatebooleanflag=true;privatefinalReadWriteLocklock=newReentrantReadWriteLock();privatefinalLockreadLock=lock.readLock();privatefinalLockwriteLock=lock.writeLock();publicvoidtoggle(){writeLock.lock();try{flag^=true;//Sameasflag=!flag;}finally{writeLock.unlock();}}publicbooleangetFlag(){readLock.lock();try{returnflag;}finally{readLock.unlock();}}}不要調(diào)用Thread.run(),不要使用Thread.stop()以終止線程保證執(zhí)行阻塞操作的線程可以終止publicfinalclassSocketReaderimplementsRunnable{privatefinalSocketChannelsc;privatefinalObjectlock=newObject();publicSocketReader(Stringhost,intport)throwsIOException{sc=SocketChannel.open(newInetSocketAddress(host,port));}@Overridepublicvoidrun(){ByteBufferbuf=ByteBuffer.allocate(1024);try{synchronized(lock){while(!Terrupted()){sc.read(buf);//...}}}catch(IOExceptionie){//Forwardtohandler}}publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{SocketReaderreader=newSocketReader("somehost",25);Threadthread=newThread(reader);thread.start();Thread.sleep(1000);errupt();}}互相依存的任務(wù)不要在一個有限的線程池執(zhí)行有限線程池指定可以同時執(zhí)行在線程池中的線程數(shù)量的上限。程序不得使用有限線程池線程執(zhí)行互相依賴的任務(wù)。也許會導(dǎo)致線程饑餓死鎖,所有的線程池執(zhí)行的任務(wù)正在等待一個可用的線程中執(zhí)行一個內(nèi)部隊列阻塞輸入輸出程序終止前刪除臨時文獻(xiàn)檢測和解決文獻(xiàn)相關(guān)的錯誤Java的文獻(xiàn)操作方法往往有一個返回值,而不是拋出一個異常,表達(dá)失敗。因此,忽略返回值文獻(xiàn)操作的程序,往往無法檢測到這些操作是否失敗。Java程序必須檢查執(zhí)行文獻(xiàn)I/O方法的返回值。不對的的寫法:Filefile=newFile(args[0]);file.delete();對的的寫法:Filefile=newFile("file");if(!file.delete()){log.error("Deletionfailed");}及時釋放資源垃圾收集器無法釋放非內(nèi)存資源,如打開的文獻(xiàn)描述符與數(shù)據(jù)庫的連接。因此,不釋放資源,也許導(dǎo)致資源耗盡襲擊。try{finalFileInputStreamstream=newFileInputStream(fileName);try{finalBufferedReaderbufRead=newBufferedReader(newInputStreamReader(stream));Stringline;while((line=bufRead.readLine())!=null){sendLine(line);}}finally{if(stream!=null){try{stream.close();}catch(IOExceptione){//forwardtohandler}}}}catch(IOExceptione){//forwardtohandler}序列化不要序列化未加密的敏感數(shù)據(jù)序列化允許一個對象的狀態(tài)被保存為一個字節(jié)序列,然后重新在稍后的時間恢復(fù),它沒有提供任何機(jī)制來保護(hù)序列化的數(shù)據(jù)。敏感的數(shù)據(jù)不應(yīng)當(dāng)被序列化的例子涉及加密密鑰,數(shù)字證書。解決方法:對于數(shù)據(jù)成員可以使用transient,聲明該數(shù)據(jù)成員是瞬態(tài)的。重寫序列化相關(guān)方法writeObject、readObject、readObjectNoData,防止被子類惡意重寫classSensitiveClassextendsNumber{//...protectedfinalObjectwriteObject(java.io.ObjectOutputStreamout)throwsNotSerializableException{thrownewNotSerializableException();}protectedfinalObjectreadObject(java.io.ObjectInputStreamin)throwsNotSeriali

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論