![java安全編碼規(guī)范_第1頁](http://file4.renrendoc.com/view11/M01/0C/3D/wKhkGWelr5CAZtRZAAFv1XwSh_U653.jpg)
![java安全編碼規(guī)范_第2頁](http://file4.renrendoc.com/view11/M01/0C/3D/wKhkGWelr5CAZtRZAAFv1XwSh_U6532.jpg)
![java安全編碼規(guī)范_第3頁](http://file4.renrendoc.com/view11/M01/0C/3D/wKhkGWelr5CAZtRZAAFv1XwSh_U6533.jpg)
![java安全編碼規(guī)范_第4頁](http://file4.renrendoc.com/view11/M01/0C/3D/wKhkGWelr5CAZtRZAAFv1XwSh_U6534.jpg)
![java安全編碼規(guī)范_第5頁](http://file4.renrendoc.com/view11/M01/0C/3D/wKhkGWelr5CAZtRZAAFv1XwSh_U6535.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
安全開發(fā)-java安全編碼規(guī)范申明:本文非筆者原創(chuàng),原文轉(zhuǎn)載自:/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%84%E8%8C%83%E6%96%87%E6%A1%A3/2018-08-17-SDL-3-java%E5%AE%89%E5%85%A8%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83.md
1輸入驗(yàn)證和數(shù)據(jù)合法性校驗(yàn)程序接受數(shù)據(jù)可能來源于未經(jīng)驗(yàn)證的用戶,網(wǎng)絡(luò)連接和其他不受信任的來源,如果未對(duì)程序接受數(shù)據(jù)進(jìn)行校驗(yàn),則可能會(huì)引發(fā)安全問題。1.1避免SQL注入使用PreparedStatement預(yù)編譯SQL,解決SQL注入問題,傳遞給PreparedStatement對(duì)象的參數(shù)可以被強(qiáng)制進(jìn)行類型轉(zhuǎn)換,確保在插入或查詢數(shù)據(jù)時(shí)與底層的數(shù)據(jù)庫格式匹配。
StringsqlString="select*fromdb_userwhereusername=?andpassword=?";PreparedStatementstmt=connection.prepareStatement(sqlString);stmt.setString(1,username);stmt.setString(2,pwd);ResultSetrs=stmt.executeQuery();1.2避免XML注入通過StringBulider或StringBuffer拼接XML文件時(shí),需對(duì)輸入數(shù)據(jù)進(jìn)行合法性校驗(yàn)。對(duì)數(shù)量quantity進(jìn)行合法性校驗(yà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();1.3避免跨站點(diǎn)腳本(XSS)對(duì)產(chǎn)生跨站的參數(shù)進(jì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{//...}2聲明和初始化2.1避免類初始化的相互依賴?yán)哄e(cuò)誤的寫法:publicclassCycle{privatefinalintbalance;privatestaticfinalCyclec=newCycle();privatestaticfinalintdeposit=(int)(Math.random()*100);//RandomdepositpublicCycle(){balance=deposit-10;//Subtractprocessingfee}publicstaticvoidmain(String[]args){System.out.println("Theaccountbalanceis:"+c.balance);}}類加載時(shí)初始化指向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);}}3表達(dá)式3.1不可忽略方法的返回值忽略方法的放回值可能會(huì)導(dǎo)致無法預(yù)料的結(jié)果。錯(cuò)誤的寫法:publicvoiddeleteFile(){FilesomeFile=newFile("someFileName.txt");someFile.delete();}正確的寫法:publicvoiddeleteFile(){FilesomeFile=newFile("someFileName.txt");if(!someFile.delete()){//handlefailuretodeletethefile}}3.2不要引用空指針當(dāng)一個(gè)變量指向一個(gè)NULL值,使用這個(gè)變量的時(shí)候又沒有檢查,這時(shí)會(huì)導(dǎo)致。NullPointerException。在使用變量前一定要做是否為NULL值的校驗(yàn)。3.3使用Arrays.equals()來比較數(shù)組的內(nèi)容數(shù)組沒有覆蓋的Object.equals()方法,調(diào)用Object.equals()方法實(shí)際上是比較數(shù)組的引用,而不是他們的內(nèi)容。程序必須使用兩個(gè)參數(shù)Arrays.equals()方法來比較兩個(gè)數(shù)組的內(nèi)容publicvoidarrayEqualsExample(){int[]arr1=newint[20];//initializedto0int[]arr2=newint[20];//initializedto0Arrays.equals(arr1,arr2);//true}4數(shù)字類型和操作4.1防止整數(shù)溢出使用java.lang.Number.BigInteger類進(jìn)行整數(shù)運(yùn)算,防止整數(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();}}4.2避免除法和取模運(yùn)算分母為零要避免因?yàn)榉帜笧榱愣鴮?dǎo)致除法和取模運(yùn)算出現(xiàn)異常。if(num2==0){//handleerror}else{result1=num1/num2;result2=num1%num2;}5類和方法操作5.1數(shù)據(jù)成員聲明為私有,提供可訪問的包裝方法攻擊者可以用意想不到的方式操縱public或protected的數(shù)據(jù)成員,所以需要將數(shù)據(jù)成員為private,對(duì)外提供可控的包裝方法訪問數(shù)據(jù)成員。5.2敏感類不允許復(fù)制包含私人的,機(jī)密或其他敏感數(shù)據(jù)的類是不允許被復(fù)制的,解決的方法有兩種:1、類聲明為finalfinalclassSensitiveClass{//...}2、Clone方法拋出CloneNotSupportedException異常classSensitiveClass{//...publicfinalSensitiveClassclone()throwsCloneNotSupportedException{thrownewCloneNotSupportedException();}}5.3比較類的正確做法如果由同一個(gè)類裝載器裝載,它們具有相同的完全限定名稱,則它們是兩個(gè)相同的類。不正確寫法://Determinewhetherobjectauthhasrequired/expectedclassobjectif(auth.getClass().getName().equals("com.application.auth.DefaultAuthenticationHandler")){//...}正確寫法://Determinewhetherobjectauthhasrequired/expectedclassnameif(auth.getClass()==com.application.auth.DefaultAuthenticationHandler.class){//...}5.4不要硬編碼敏感信息硬編碼的敏感信息,如密碼,服務(wù)器IP地址和加密密鑰,可能會(huì)泄露給攻擊者。敏感信息均必須存在在配置文件或數(shù)據(jù)庫中。5.5驗(yàn)證方法參數(shù)驗(yàn)證方法的參數(shù),可確保操作方法的參數(shù)產(chǎn)生有效的結(jié)果。不驗(yàn)證方法的參數(shù)可能會(huì)導(dǎo)致不正確的計(jì)算,運(yùn)行時(shí)異常,違反類的不變量,對(duì)象的狀態(tài)不一致。對(duì)于跨信任邊界接收參數(shù)的方法,必須進(jìn)行參數(shù)合法性校驗(yàn)privateObjectmyState=null;//對(duì)于修改myState方法的入?yún)ⅲM(jìn)行非空和合法性校驗(yàn)voidsetState(Objectstate){
if(state==null){
//Handlenullstate
}
if(isInvalidState(state)){
//Handleinvalidstate
}
myState=state;}5.6不要使用過時(shí)、陳舊或低效的方法在程序代碼中使用過時(shí)的、陳舊的或低效的類或方法可能會(huì)導(dǎo)致錯(cuò)誤的行為。5.7數(shù)組引用問題某個(gè)方法返回一個(gè)對(duì)敏感對(duì)象的內(nèi)部數(shù)組的引用,假定該方法的調(diào)用程序不改變這些對(duì)象。即使數(shù)組對(duì)象本身是不可改變的,也可以在數(shù)組對(duì)象以外操作數(shù)組的內(nèi)容,這種操作將反映在返回該數(shù)組的對(duì)象中。如果該方法返回可改變的對(duì)象,外部實(shí)體可以改變?cè)谀莻€(gè)類中聲明的public變量,這種改變將反映在實(shí)際對(duì)象中。不正確的寫法:publicclassXXX{ privateString[]xxxx; publicString[]getXXX(){ returnxxxx; }}正確的寫法:publicclassXXX{ privateString[]xxxx; publicString[]getXXX(){ Stringtemp[]=Arrays.copyof(…);//或其他數(shù)組復(fù)制方法 returntemp; }}5.8不要產(chǎn)生內(nèi)存泄露垃圾收集器只收集不可達(dá)的對(duì)象,因此,存在未使用的可到達(dá)的對(duì)象,仍然表示內(nèi)存管理不善。過度的內(nèi)存泄漏可能會(huì)導(dǎo)致內(nèi)存耗盡,拒絕服務(wù)(DoS)。6異常處理6.1不要忽略捕獲的異常對(duì)于捕獲的異常要進(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}}}6.2不允許暴露異常的敏感信息沒有過濾敏感信息的異常堆棧往往會(huì)導(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;}}}6.3不允許拋出RuntimeException,Exception,Throwable不正確的寫法:booleanisCapitalized(Strings){if(s==null){thrownewRuntimeException("NullString");}}privatevoiddoSomething()throwsException{//...}正確寫法:booleanisCapitalized(Strings){if(s==null){thrownewNullPointerException();}}privatevoiddoSomething()throwsIOException{//...}6.4不要捕獲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]));}7多線程編程7.1確保共享變量的可見性對(duì)于共享變量,要確保一個(gè)線程對(duì)它的改動(dòng)對(duì)其他線程是可見的。線程可能會(huì)看到一個(gè)陳舊的共享變量的值。為了共享變量是最新的,可以將變量聲明為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;}}7.2確保共享變量的操作是原子的除了要確保共享變量的更新對(duì)其他線程可見的,還需要確保對(duì)共享變量的操作是原子的,這時(shí)將共享變量聲明為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();}}}7.3不要調(diào)用Thread.run(),不要使用Thread.stop()以終止線程7.4確保執(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();}}7.5相互依存的任務(wù)不要在一個(gè)有限的線程池執(zhí)行有限線程池指定可以同時(shí)執(zhí)行在線程池中的線程數(shù)量的上限。程序不得使用有限線程池線程執(zhí)行相互依賴的任務(wù)。可能會(huì)導(dǎo)致線程饑餓死鎖,所有的線程池執(zhí)行的任務(wù)正在等待一個(gè)可用的線程中執(zhí)行一個(gè)內(nèi)部隊(duì)列阻塞8輸入輸出8.1程序終止前刪除臨時(shí)文件8.2檢測(cè)和處理文件相關(guān)的錯(cuò)誤Java的文件操作方法往往有一個(gè)返回值,而不是拋出一個(gè)異常,表示失敗。因此,忽略返回值文件操作的程序,往往無法檢測(cè)到這些操作是否失敗。Java程序必須檢查執(zhí)行文件I/O方法的返回值。不正確的寫法:Filefile=newFile(args[0]);file.delete();正確的寫法:Filefile=newFile("file");if(!file.delete()){log.error("Deletionfailed");}8.3及時(shí)釋放資源垃圾收集器無法釋放非內(nèi)存資源,如打開的文件描述符與數(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}9序列化9.1不要序列化未加密的敏感數(shù)據(jù)序列化允許一個(gè)對(duì)象的狀態(tài)被保存為一個(gè)字節(jié)序列,然后重新在稍后的時(shí)間恢復(fù),它沒有提供任何機(jī)制來保護(hù)序列化的數(shù)據(jù)。敏感的數(shù)據(jù)不應(yīng)該被序列化的例子包括加密密鑰,數(shù)字證書。解決方法:對(duì)于數(shù)據(jù)成員可以使用transient,聲明該數(shù)據(jù)成員是瞬態(tài)的。重寫序列化相關(guān)方法writeObject、readObject、readObjectNoData,防止被子類惡意重寫classSensitiveClassextendsNumber{//...protectedfinalObjectwriteObject(java.io.ObjectOutputStreamout)throwsNotSerializableException{thrownewNotSerializableException();}protectedfinalObjectreadObject(java.io.ObjectInputStreamin)throwsNotSerializableException{thrownewNotSerializableException();}protectedfinalObjectreadObjectNoData(java.io.ObjectInputStreamin)throwsNotSerializableException{thrownewNotSerializableException();}}9.2在序列化過程中避免內(nèi)存和資源泄漏不正確的寫法:classSensorDataimplementsSerializable{//1MBofdataperinstance!publicstaticSensorDatareadSensorData(){...}publicstaticbooleanisAvailable(){...}}classSerializeSensorData{publicstaticvoidmain(String[]args)throwsIOException{ObjectOutputStreamout=null;try{out=newObjectOutputStream(newBufferedOutputStream(newFileOutputStream("ser.dat")));while(SensorData.isAvailable()){//notethateachSensorDataobjectis1MBinsizeSensorDatasd=SensorData.readSensorData();out.writeObject(sd);}}finally{if(out!=null){out.close();}}}}正確寫法:classSerializeSensorData{publicstaticvoidmain(String[]args)throwsIOException{ObjectOutputStreamout=null;try{out=newObjectOutputStream(newBufferedOutputStream(newFileOutputStream("ser.dat")));while(SensorData.isAvailable()){//notethateachSensorDataobjectis1MBinsizeSensorDatasd=SensorData.readSensorData();out.writeObject(sd);out.reset();//resetthestream}}finally{if(out!=null){out.close();}}}}9.3反序列化要在程序最小權(quán)限的安全環(huán)境中(完成)JAVA安全編碼規(guī)范\t"/weixin_39997829/article/details/_blank"安全小哥
2021-11-1017:04:21
100
收藏
1分類專欄:
\t"/weixin_39997829/article/details/_blank"JAVA代碼審計(jì)
文章標(biāo)簽:
\t"/weixin_39997829/article/details/_blank"java
\t"/weixin_39997829/article/details/_blank"安全
\t"/weixin_39997829/article/details/_blank"開發(fā)語言版權(quán)\o"JAVA代碼審計(jì)"\t"/weixin_39997829/article/details/_blank"JAVA代碼審計(jì)專欄收錄該內(nèi)容19篇文章8訂閱訂閱專欄Java安全編碼規(guī)范-1.0.6byk4n5ha0\o"Java安全編碼規(guī)范-1.0.6byk4n5ha0"Java安全編碼規(guī)范-1.0.6byk4n5ha0\o"編寫依據(jù)與參考文件:"編寫依據(jù)與參考文件:\o"1.《信息安全技術(shù)應(yīng)用軟件安全編程指南》(國標(biāo)GBT38674-2020)"1.《信息安全技術(shù)應(yīng)用軟件安全編程指南》(國標(biāo)GBT38674-2020)\o"2.《CommonWeaknessEnumeration》-國際通用計(jì)算機(jī)軟件缺陷字典"2.《CommonWeaknessEnumeration》-國際通用計(jì)算機(jī)軟件缺陷字典\o"3.《OWASPTop102017》-2017年十大Web應(yīng)用程序安全風(fēng)險(xiǎn)"3.《OWASPTop102017》-2017年十大Web應(yīng)用程序安全風(fēng)險(xiǎn)\o"4.《fortify-代碼審計(jì)規(guī)則》"4.《fortify-代碼審計(jì)規(guī)則》\o"5.《java開發(fā)手冊(cè)》(阿里巴巴出品)"5.《java開發(fā)手冊(cè)》(阿里巴巴出品)\o"第一條設(shè)計(jì)開發(fā)必須符合概要設(shè)計(jì)及安全防護(hù)方案"第一條設(shè)計(jì)開發(fā)必須符合概要設(shè)計(jì)及安全防護(hù)方案\o"項(xiàng)目管理要求↓:"項(xiàng)目管理要求↓:\o"第二條上線代碼必須進(jìn)行嚴(yán)格的安全測(cè)試并進(jìn)行軟著備案"第二條上線代碼必須進(jìn)行嚴(yán)格的安全測(cè)試并進(jìn)行軟著備案\o"項(xiàng)目管理要求↓:"項(xiàng)目管理要求↓:\o"第三條嚴(yán)格限制帳號(hào)訪問權(quán)限"第三條嚴(yán)格限制帳號(hào)訪問權(quán)限\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"第四條提供完備的安全審計(jì)功能"第四條提供完備的安全審計(jì)功能\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"第五條采取有效措施保證認(rèn)證安全"第五條采取有效措施保證認(rèn)證安全\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"第六條保證代碼簡(jiǎn)潔、注釋明確"第六條保證代碼簡(jiǎn)潔、注釋明確\o"安全編碼要求↓:"安全編碼要求↓:\o"第七條使用安全函數(shù)和安全規(guī)范驗(yàn)證所有外部輸入"第七條使用安全函數(shù)和安全規(guī)范驗(yàn)證所有外部輸入\o"安全編碼要求↓:"安全編碼要求↓:\o"HTTP參數(shù)污染"HTTP參數(shù)污染\o"不受信任的查詢字符串"不受信任的查詢字符串\o"不受信任的HTTP請(qǐng)求頭"不受信任的HTTP請(qǐng)求頭\o"1.不受信任的Cookie頭"1.不受信任的Cookie頭\o"2.不受信任的Content-Type請(qǐng)求頭"2.不受信任的Content-Type請(qǐng)求頭\o"3.不受信任的HOST請(qǐng)求頭"3.不受信任的HOST請(qǐng)求頭\o"4.不受信任的User-Agent請(qǐng)求頭"4.不受信任的User-Agent請(qǐng)求頭\o"5.不受信任的IP請(qǐng)求頭"5.不受信任的IP請(qǐng)求頭\o"缺少CSRF攻擊的防護(hù)"缺少CSRF攻擊的防護(hù)\o"客戶端請(qǐng)求偽造"客戶端請(qǐng)求偽造\o"服務(wù)端請(qǐng)求偽造"服務(wù)端請(qǐng)求偽造\o"惡意的命令注入"惡意的命令注入\o"不安全的反序列化"不安全的反序列化\o"1.配置全局反序列化白名單"1.配置全局反序列化白名單\o"2.jackson安全反序列化編碼示例"2.jackson安全反序列化編碼示例\o"3.fastjson安全反序列化編碼示例"3.fastjson安全反序列化編碼示例\o"4.XStream安全反序列化編碼示例"4.XStream安全反序列化編碼示例\o"5.shiro安全反序列化編碼示例"5.shiro安全反序列化編碼示例\o"XML外部實(shí)體(XXE)攻擊"XML外部實(shí)體(XXE)攻擊\o"1.XStream"1.XStream\o"2.javax.xml.parsers.DocumentBuilderFactory"2.javax.xml.parsers.DocumentBuilderFactory\o"3.org.jdom2.input.SAXBuilder"3.org.jdom2.input.SAXBuilder\o"4.javax.xml.parsers.SAXParserFactory"4.javax.xml.parsers.SAXParserFactory\o"5.org.dom4j.io.SAXReader"5.org.dom4j.io.SAXReader\o"6.org.xml.sax.XMLReader"6.org.xml.sax.XMLReader\o"7.javax.xml.transform.sax.SAXTransformerFactory"7.javax.xml.transform.sax.SAXTransformerFactory\o"8.javax.xml.validation.SchemaFactory"8.javax.xml.validation.SchemaFactory\o"9.javax.xml.transform.TransformerFactory"9.javax.xml.transform.TransformerFactory\o"XPath注入"XPath注入\o"EL表達(dá)式引擎代碼注入"EL表達(dá)式引擎代碼注入\o"JS腳本引擎代碼注入"JS腳本引擎代碼注入\o"JavaBeans屬性注入"JavaBeans屬性注入\o"不安全的對(duì)象綁定"不安全的對(duì)象綁定\o"正則表達(dá)式DOS(ReDOS)"正則表達(dá)式DOS(ReDOS)\o"跨站腳本攻擊(XSS)"跨站腳本攻擊(XSS)\o"第八條必須過濾上傳文件"第八條必須過濾上傳文件\o"安全編碼要求↓:"安全編碼要求↓:\o"潛在的路徑遍歷(讀取文件)"潛在的路徑遍歷(讀取文件)\o"潛在的路徑遍歷(寫入文件)"潛在的路徑遍歷(寫入文件)\o"第九條確保多線程編程的安全性"第九條確保多線程編程的安全性\o"安全編碼要求↓:"安全編碼要求↓:\o"競(jìng)爭(zhēng)條件"競(jìng)爭(zhēng)條件\o"第十條設(shè)計(jì)錯(cuò)誤、異常處理機(jī)制"第十條設(shè)計(jì)錯(cuò)誤、異常處理機(jī)制\o"安全編碼要求↓:"安全編碼要求↓:\o"第十一條數(shù)據(jù)庫操作使用參數(shù)化請(qǐng)求方式"第十一條數(shù)據(jù)庫操作使用參數(shù)化請(qǐng)求方式\o"安全編碼要求↓:"安全編碼要求↓:\o"SQL注入"SQL注入\o"1.jdbc安全編碼規(guī)范"1.jdbc安全編碼規(guī)范\o"2.Mybatis安全編碼規(guī)范"2.Mybatis安全編碼規(guī)范\o"LDAP注入"LDAP注入\o"第十二條禁止在源代碼中寫入口令、服務(wù)器IP等敏感信息"第十二條禁止在源代碼中寫入口令、服務(wù)器IP等敏感信息\o"安全編碼要求↓:"安全編碼要求↓:\o"硬編碼密碼"硬編碼密碼\o"硬編碼密鑰"硬編碼密鑰\o"第十三條為所有敏感信息采用加密傳輸"第十三條為所有敏感信息采用加密傳輸\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"名稱類信息脫敏規(guī)則:"名稱類信息脫敏規(guī)則:\o"聯(lián)系類信息脫敏規(guī)則:"聯(lián)系類信息脫敏規(guī)則:\o"證件號(hào)脫敏規(guī)則:"證件號(hào)脫敏規(guī)則:\o"安全編碼要求↓:"安全編碼要求↓:\o"接受任何證書的TrustManager"接受任何證書的TrustManager\o"接受任何簽名證書的HostnameVerifier"接受任何簽名證書的HostnameVerifier\o"第十四條使用可信的密碼算法"第十四條使用可信的密碼算法\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"禁止使用弱加密"禁止使用弱加密\o"安全編碼要求↓:"安全編碼要求↓:\o"可預(yù)測(cè)的偽隨機(jī)數(shù)生成器"可預(yù)測(cè)的偽隨機(jī)數(shù)生成器\o"錯(cuò)誤的十六進(jìn)制串聯(lián)"錯(cuò)誤的十六進(jìn)制串聯(lián)\o"第十五條禁止在日志、表單、cookie等文件中記錄口令、銀行賬號(hào)、通信內(nèi)容等敏感數(shù)據(jù)"第十五條禁止在日志、表單、cookie等文件中記錄口令、銀行賬號(hào)、通信內(nèi)容等敏感數(shù)據(jù)\o"安全編碼要求↓:"安全編碼要求↓:\o"Cookie中的潛在敏感數(shù)據(jù)"Cookie中的潛在敏感數(shù)據(jù)\o"日志偽造"日志偽造\o"HTTP響應(yīng)截?cái)?HTTP響應(yīng)截?cái)郳o"第十六條禁止高風(fēng)險(xiǎn)的服務(wù)及協(xié)議"第十六條禁止高風(fēng)險(xiǎn)的服務(wù)及協(xié)議\o"程序設(shè)計(jì)要求↓:"程序設(shè)計(jì)要求↓:\o"安全編碼要求↓:"安全編碼要求↓:\o"不安全的HTTP動(dòng)詞"不安全的HTTP動(dòng)詞\o"第十七條避免異常信息泄漏"第十七條避免異常信息泄漏\o"安全編碼要求↓:"安全編碼要求↓:\o"意外的屬性泄露"意外的屬性泄露\o"不安全的SpringBootActuator暴露"不安全的SpringBootActuator暴露\o"不安全的Swagger暴露"不安全的Swagger暴露\o"第十八條嚴(yán)格會(huì)話管理"第十八條嚴(yán)格會(huì)話管理\o"安全編碼要求↓:"安全編碼要求↓:\o"缺少HttpOnly標(biāo)志的Cookie"缺少HttpOnly標(biāo)志的Cookie\o"不安全的CORS策略"不安全的CORS策略\o"不安全的永久性Cookie"不安全的永久性Cookie\o"不安全的廣播(Android)"不安全的廣播(Android)編寫依據(jù)與參考文件:1.《信息安全技術(shù)應(yīng)用軟件安全編程指南》(國標(biāo)GBT38674-2020)2.《CommonWeaknessEnumeration》-國際通用計(jì)算機(jī)軟件缺陷字典3.《OWASPTop102017》-2017年十大Web應(yīng)用程序安全風(fēng)險(xiǎn)4.《fortify-代碼審計(jì)規(guī)則》5.《java開發(fā)手冊(cè)》(阿里巴巴出品)第一條設(shè)計(jì)開發(fā)必須符合概要設(shè)計(jì)及安全防護(hù)方案項(xiàng)目管理要求↓:所有項(xiàng)目必須參照《概要設(shè)計(jì)》編寫《安全防護(hù)方案》,兩者均評(píng)審?fù)ㄟ^后才能啟動(dòng)編碼工作。java8版本應(yīng)不低于jdk-1.8_291java11版本應(yīng)不低于jdk-11.0.11第二條上線代碼必須進(jìn)行嚴(yán)格的安全測(cè)試并進(jìn)行軟著備案項(xiàng)目管理要求↓:所有項(xiàng)目必須完成安全自測(cè)和第三方安全測(cè)試,并完成軟著相關(guān)工作才能上線運(yùn)行,上線運(yùn)行版本必須與測(cè)試通過版本一致。第三條嚴(yán)格限制帳號(hào)訪問權(quán)限程序設(shè)計(jì)要求↓:應(yīng)用程序除公共功能外,禁止不同角色之間可以跨角色訪問其他角色的功能。例如:某互斥業(yè)務(wù)名為“發(fā)票打印”涉及三個(gè)子菜單,該業(yè)務(wù)是角色“會(huì)計(jì)”的專有功能。角色“會(huì)計(jì)”可以看到發(fā)票打印相關(guān)的三個(gè)子菜單并正常操作。角色“出納”無法看到三個(gè)子菜單并無法訪問該三個(gè)子菜單中對(duì)應(yīng)的所有后端接口。如果“出納”可以訪問或操作“會(huì)計(jì)”的“發(fā)票打印”或其他“會(huì)計(jì)”專有的功能則應(yīng)判定為越權(quán)。當(dāng)用戶訪問無權(quán)限的菜單url或者接口url:后臺(tái)的HTTP響應(yīng)碼禁止返回200。HTTP的響應(yīng)包body內(nèi)容必須返回“無權(quán)限”。原則禁止存在“記住密碼”的功能。第四條提供完備的安全審計(jì)功能程序設(shè)計(jì)要求↓:用戶在系統(tǒng)中只要在頁面中存在點(diǎn)擊、輸入、拖拽等操作行為,日志記錄中應(yīng)當(dāng)針對(duì)操作行為產(chǎn)生日志。一條日志所包含的字段應(yīng)包括:事件的日期(年月日)時(shí)間(時(shí)分秒)事件類型(系統(tǒng)級(jí)、業(yè)務(wù)級(jí)二選一)登錄ID姓名IP地址事件描述(用戶主體對(duì)什么客體執(zhí)行了什么操作?該操作的增刪改查的內(nèi)容又是什么?)事件結(jié)果(成功、失敗)第五條采取有效措施保證認(rèn)證安全程序設(shè)計(jì)要求↓:如果用戶連續(xù)登錄失?。ㄗ疃嗍?0次),應(yīng)將該用戶鎖定,禁止其登陸。外網(wǎng)系統(tǒng)用戶登錄時(shí),應(yīng)使用短信進(jìn)行二次驗(yàn)證可以保證用戶登錄的安全性。用戶登錄失敗時(shí),應(yīng)提示“用戶名或口令錯(cuò)誤”,禁止提示“用戶名不存在”或“登錄口令錯(cuò)誤”。用戶登錄時(shí),必須使用合規(guī)的加密方案加密傳輸用戶的登錄名和密碼。合規(guī)的雙向加密數(shù)據(jù)的傳輸方案:1)后端生成非對(duì)稱算法(國密SM2、RSA2048)的公鑰B1、私鑰B2,前端訪問后端獲取公鑰B1。2)前端每次發(fā)送請(qǐng)求前,隨機(jī)生成對(duì)稱算法(國密SM4、AES256)的密鑰A1。3)公鑰、私鑰可以全系統(tǒng)固定為一對(duì),前端可以儲(chǔ)存公鑰,但私鑰不能保存在后端數(shù)據(jù)庫中。4)前端用步驟2的密鑰A1加密所有業(yè)務(wù)數(shù)據(jù)生成encrypt_data,用步驟1獲取的公鑰B1加密密鑰A1生成encrypt_key。5)前端用哈希算法對(duì)encrypt_data+encrypt_key的值形成一個(gè)校驗(yàn)值check_hash。6)前端將encrypt_data、encrypt_key、check_hash三個(gè)參數(shù)包裝在同一個(gè)http數(shù)據(jù)包中發(fā)送到后端。7)后端獲取三個(gè)參數(shù)后先判斷哈希值check_hash是否匹配encrypt_data+encrypt_key以驗(yàn)證完整性。8)后端用私鑰B2解密encrypt_key獲取本次請(qǐng)求的對(duì)稱算法的密鑰A1。9)后端使用步驟8獲取的密鑰A1解密encrypt_data獲取實(shí)際業(yè)務(wù)數(shù)據(jù)。10)后端處理完業(yè)務(wù)邏輯后,將需要返回的信息使用密鑰A1進(jìn)行加密后回傳給前端。11)加密數(shù)據(jù)回傳給前端后,前端使用A1對(duì)加密的數(shù)據(jù)進(jìn)行解密獲得返回的信息。12)步驟2隨機(jī)生成的密鑰A1已經(jīng)使用完畢,前端應(yīng)將其銷毀。前端發(fā)送請(qǐng)求時(shí)必須設(shè)計(jì)防篡改和防重放攻擊的安全邏輯,后端必須開展對(duì)應(yīng)的校驗(yàn)。合規(guī)的防篡改和防重放攻擊的傳輸方案:1)客戶端獲取公鑰時(shí)應(yīng)同時(shí)獲取后端服務(wù)器時(shí)間,保證客戶端和服務(wù)器時(shí)間一致。2)前端每次發(fā)送請(qǐng)求前,應(yīng)在header請(qǐng)求頭中添加時(shí)間戳字段。3)通過url+時(shí)間戳+用戶token+http請(qǐng)求體(可以為空)產(chǎn)生sign簽名。4)將sign簽名添加到header請(qǐng)求頭中后發(fā)送請(qǐng)求。5)后端校驗(yàn)sign簽名是否正確,如果簽名校驗(yàn)不通過應(yīng)提示"數(shù)據(jù)被篡改"并丟棄當(dāng)前請(qǐng)求。6)如果時(shí)間戳的時(shí)間和服務(wù)器時(shí)間相差大于10秒,應(yīng)丟棄當(dāng)前請(qǐng)求。7)后臺(tái)應(yīng)緩存每一個(gè)sign值10秒,在10秒內(nèi)如果出現(xiàn)包含同一個(gè)sign值的請(qǐng)求,應(yīng)丟棄當(dāng)前請(qǐng)求。8)用戶token中部分?jǐn)?shù)據(jù)(禁止全部)應(yīng)存儲(chǔ)在sessionStorage中,以保證頁面關(guān)閉后登錄失效。第六條保證代碼簡(jiǎn)潔、注釋明確安全編碼要求↓:應(yīng)持續(xù)執(zhí)行代碼審計(jì)工作。代碼中禁止出現(xiàn)goto語句。應(yīng)禁止使用遞歸并及時(shí)去除程序中冗余的功能代碼。第七條使用安全函數(shù)和安全規(guī)范驗(yàn)證所有外部輸入安全編碼要求↓:HTTP參數(shù)污染如果應(yīng)用程序未正確校驗(yàn)用戶輸入的數(shù)據(jù),則惡意用戶可能會(huì)破壞應(yīng)用程序的邏輯以執(zhí)行針對(duì)客戶端或服務(wù)器端的攻擊。脆弱代碼1://攻擊者可以提交lang的內(nèi)容為://en&user_id=1#//致使攻擊者可以隨意篡改user_id的值Stringlang=request.getParameter("lang");GetMethodget=newGetMethod("");//攻擊者提交lang=en&user_id=1#&user_id=123可覆蓋原始user_id的值get.setQueryString("lang="+lang+"&user_id="+user_id);get.execute();解決方案1://參數(shù)化綁定URIBuilderuriBuilder=newURIBuilder("/viewDetails");uriBuilder.addParameter("lang",input);uriBuilder.addParameter("user_id",userId);HttpGethttpget=newHttpGet(uriBuilder.build().toString());脆弱邏輯2:訂單系統(tǒng)計(jì)算訂單的價(jià)格步驟1:訂單總價(jià)=商品1單價(jià)*商品1數(shù)量+商品2單價(jià)*商品2數(shù)量+...步驟2:錢包余額=錢包金額-訂單總價(jià)當(dāng)攻擊者將商品數(shù)量都篡改為負(fù)數(shù),導(dǎo)致步驟1的訂單總價(jià)為負(fù)數(shù)。而負(fù)負(fù)得正,攻擊者不僅買入了商品并且錢包金額也增長了。解決方案2:應(yīng)在后臺(tái)嚴(yán)格校驗(yàn)訂單中每一個(gè)輸入?yún)?shù)的長度、格式、邏輯、特殊字符。整體解決方案:應(yīng)按照長度、格式、邏輯以及特殊字符4個(gè)維度對(duì)每一個(gè)輸入?yún)?shù)進(jìn)行安全校驗(yàn),然后再將其傳遞給敏感的API。原則上數(shù)據(jù)庫主鍵不能使用自增純數(shù)字,應(yīng)使用uuid或雪花算法作為數(shù)據(jù)庫表主鍵以保證唯一性和不可預(yù)測(cè)性。身份信息應(yīng)使用當(dāng)前請(qǐng)求的用戶session或token安全的獲取,禁止直接信任用戶提交的身份信息。安全獲取用戶身份后,應(yīng)對(duì)請(qǐng)求的數(shù)據(jù)資源進(jìn)行邏輯判斷,防止用戶操作無權(quán)限的數(shù)據(jù)資源。不受信任的查詢字符串查詢字符串是GET參數(shù)名稱和值的串聯(lián),可以傳入非預(yù)期參數(shù)。風(fēng)險(xiǎn):例如URL請(qǐng)求/app/servlet.htm?a=1&b=2則對(duì)應(yīng)查詢字符串提取為a=1&b=2那么HttpServletRequest.getParameter()HttpServletRequest.getQueryString()獲取的值都可能是不安全的。解決方案:查詢字符串只能在頁面渲染時(shí)使用,禁止將查詢字符串關(guān)聯(lián)任何業(yè)務(wù)請(qǐng)求。應(yīng)按照長度、格式、邏輯以及特殊字符4個(gè)維度對(duì)每一個(gè)輸入的查詢字符串參數(shù)進(jìn)行安全校驗(yàn),然后再將其傳遞給敏感的API。不受信任的HTTP請(qǐng)求頭攻擊者可以惡意篡改或偽造所有http請(qǐng)求頭中的參數(shù),達(dá)到破壞應(yīng)用程序的邏輯以執(zhí)行針對(duì)客戶端或服務(wù)器端的目的。1.不受信任的Cookie頭HttpServletRequest.getRequestedSessionId()可以返回JSESSIONID的值。該值通常是字母、數(shù)字的組合值。(例如JSESSIONID=jp6q31lq2myn)攻擊者向后端發(fā)起請(qǐng)求時(shí)可以惡意偽造或篡改該值。例如:GET/somePageHTTP/1.1Host:User-Agent:Mozilla/5.0Cookie:JSESSIONID=Anyvalueoftheuser'schoice!!??'''">脆弱代碼:Cookie[]cookies=request.getCookies();for(inti=0;i<cookies.length;i++){Cookiec=cookies[i];if(c.getName().equals("authenticated")&&Boolean.TRUE.equals(c.getValue())){authenticated=true;}}以上代碼直接從cookie中而不是session中提取了參數(shù)作為登錄狀態(tài)的判斷,導(dǎo)致攻擊者可以偽造登錄狀態(tài)。解決方案:身份信息應(yīng)使用當(dāng)前請(qǐng)求的用戶session或token安全的獲取,而不是直接采用用戶提交的身份信息。身份信息應(yīng)僅用于查看其值是否與請(qǐng)求的資源權(quán)限(包括菜單URL、接口URL、業(yè)務(wù)數(shù)據(jù))是否匹配。如果權(quán)限不匹配,應(yīng)停止業(yè)務(wù)邏輯并立刻告警,同時(shí)在審計(jì)日志中記錄一條越權(quán)日志。身份信息的值禁止記錄到日志中,否則內(nèi)部人員可以劫持處于活動(dòng)狀態(tài)的用戶權(quán)限。2.不受信任的Content-Type請(qǐng)求頭HTTP請(qǐng)求頭Content-Type可以由惡意的攻擊者控制。因此,HTTP的Content-Type值不應(yīng)在任何重要的邏輯流程中使用。3.不受信任的HOST請(qǐng)求頭ServletRequest.getServerName()和HttpServletRequest.getHeader("Host")具有相同的邏輯,即提取Host請(qǐng)求頭。GET/testpageHTTP/1.1Host:因?yàn)閻阂獾墓粽呖梢詡卧霩ost請(qǐng)求頭,所以HTTP的Host值不應(yīng)在任何重要的邏輯流程中使用。4.不受信任的User-Agent請(qǐng)求頭請(qǐng)求頭User-Agent很容易被客戶端偽造,不建議基于User-Agent的值采用不同的安全校驗(yàn)邏輯。5.不受信任的IP請(qǐng)求頭以下IP請(qǐng)求頭,很容易被客戶端偽造,可能導(dǎo)致IP地址欺騙。X-Forwarded-ForX-Originating-IPX-Real-IPx-Remote-addrx-Remote-IP等其他解決方案1:應(yīng)用程序與用戶間無代理時(shí),應(yīng)使用getRemoteAddr函數(shù)獲取用戶ip。解決方案2:應(yīng)用程序與用戶間存在代理時(shí),應(yīng)使用代理頭獲取用戶ip。privateStringgetIpAddr(HttpServletRequestrequest){Stringip=request.getHeader("x-forwarded-for");System.out.println("x-forwarded-forip:"+ip);if(ip!=null&&ip.length()!=0&&!"unknown".equalsIgnoreCase(ip)){//多次反向代理后會(huì)有多個(gè)ip值,第一個(gè)ip才是真實(shí)ipif(ip.indexOf(",")!=-1){ip=ip.split(",")[0];}}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getHeader("Proxy-Client-IP");System.out.println("Proxy-Client-IPip:"+ip);}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getHeader("WL-Proxy-Client-IP");System.out.println("WL-Proxy-Client-IPip:"+ip);}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getHeader("HTTP_CLIENT_IP");System.out.println("HTTP_CLIENT_IPip:"+ip);}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getHeader("HTTP_X_FORWARDED_FOR");System.out.println("HTTP_X_FORWARDED_FORip:"+ip);}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getHeader("X-Real-IP");System.out.println("X-Real-IPip:"+ip);}if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){ip=request.getRemoteAddr();System.out.println("getRemoteAddrip:"+ip);}System.out.println("獲取客戶端ip:"+ip);returnip;}缺少CSRF攻擊的防護(hù)風(fēng)險(xiǎn)1:惡意用戶可以將惡意值分配給Referer請(qǐng)求頭進(jìn)行Referer請(qǐng)求偽造攻擊。如果請(qǐng)求是從另一個(gè)安全的來源(HTTPS)發(fā)起的,則Referer將不存在。脆弱代碼2:@EnableWebSecuritypublicclassWebSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{//禁用csrf保護(hù)會(huì)導(dǎo)致csrf攻擊的產(chǎn)生http.csrf().disable();}}解決方案:任何越權(quán)判讀都不應(yīng)基于Referer的值,應(yīng)判斷session或token。應(yīng)校驗(yàn)Referer值阻止來自站外的請(qǐng)求,以避免csrf攻擊。避免Referer值欺騙攻擊,例如sec_部分匹配sec_的情況。任何CSRF防護(hù)都不應(yīng)僅僅只基于Referer值,可以采用一次性的表單token。禁用SpringSecurity的CSRF保護(hù)對(duì)于標(biāo)準(zhǔn)Web應(yīng)用程序是不安全的。客戶端請(qǐng)求偽造當(dāng)Web應(yīng)用程序?qū)⒂脩糁囟ㄏ虿⑥D(zhuǎn)發(fā)到其他頁面或其他外部網(wǎng)站,如果不驗(yàn)證這些頁面的可信度,攻擊者可以將受害者重定向到網(wǎng)絡(luò)釣魚或惡意軟件站點(diǎn),或者惡意利用轉(zhuǎn)發(fā)來訪問未經(jīng)授權(quán)的頁面。脆弱代碼1:@RequestMapping("/redirect")publicStringredirect(@RequestParam("url")Stringurl){//不執(zhí)行校驗(yàn)就直接跳轉(zhuǎn)return"redirect:"+url;}脆弱代碼2:protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{//不執(zhí)行校驗(yàn)就直接跳轉(zhuǎn)resp.sendRedirect(req.getParameter("redirectUrl"));}誘使用戶訪問惡意URL(將website偽造成vvebsite):\o"/login?redirect=/fake/login"/login?redirect=/fake/login將用戶重定向到偽造的登錄頁面,該頁面看起來像他們信任的站點(diǎn):\o"/fake/login"/fake/login用戶輸入其憑據(jù)。惡意站點(diǎn)竊取用戶的憑據(jù),并將其重定向到原始網(wǎng)站。解決方案:完整URL格式:protocol://hostname[:port]/path/[;parameters][?query]#fragment禁止直接接受來自用戶的URL目標(biāo),所有URL請(qǐng)求應(yīng)使用白名單校驗(yàn)。原則上應(yīng)接受相對(duì)路徑請(qǐng)求。而絕對(duì)路徑的URL應(yīng)盡可能使用白名單校驗(yàn)每一個(gè)格式參數(shù)。驗(yàn)證URL的域名部分時(shí)應(yīng)避免sec_部分匹配sec_的惡意偽造??梢允褂霉S成涞侥繕?biāo)地址,并使用哈希在URL白名單中查找合法目標(biāo)。服務(wù)端請(qǐng)求偽造當(dāng)Web應(yīng)用程序根據(jù)用戶請(qǐng)求對(duì)數(shù)據(jù)資源發(fā)起請(qǐng)求,如果不對(duì)該數(shù)據(jù)資源執(zhí)行安全校驗(yàn),攻擊者可能獲取敏感數(shù)據(jù)資源。脆弱代碼:@WebServlet("/downloadServlet")publicclassdownloadServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{this.doGet(request,response);}protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{Stringfilename="1.txt";//沒有校驗(yàn)url變量的安全性Stringurl=request.getParameter("url");response.setHeader("content-disposition","attachment;fileName="+filename);intlen;OutputStreamoutputStream=response.getOutputStream();//直接使用url變量導(dǎo)致任意文件讀取URLfile=newURL(url);byte[]bytes=newbyte[1024];InputStreaminputStream=file.openStream();while((len=inputStream.read(bytes))>0){outputStream.write(bytes,0,len);}}}使用以下請(qǐng)求可以下載服務(wù)器硬盤上的文件http://localhost:8080/downloadServlet?url=file:///c:\1.txt解決方案:完整URL格式:protocol://hostname[:port]/path/[;parameters][?query]#fragment禁止直接接受來自用戶的URL目標(biāo),所有URL請(qǐng)求應(yīng)使用白名單校驗(yàn)。原則上應(yīng)接受相對(duì)路徑請(qǐng)求。而絕對(duì)路徑的URL應(yīng)盡可能使用白名單校驗(yàn)每一個(gè)格式參數(shù)。驗(yàn)證URL的域名部分時(shí)應(yīng)避免sec_部分匹配se
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國三羥基丙烷數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025年烘焙奶粉項(xiàng)目可行性研究報(bào)告
- 2025年水管接頭配件項(xiàng)目可行性研究報(bào)告
- 2025年支撐座項(xiàng)目可行性研究報(bào)告
- 2025年割草機(jī)電機(jī)項(xiàng)目可行性研究報(bào)告
- 2025年五位超載保護(hù)插座項(xiàng)目可行性研究報(bào)告
- 2025至2030年鍵盤開關(guān)項(xiàng)目投資價(jià)值分析報(bào)告
- 2025版社區(qū)垃圾分類回收與運(yùn)輸服務(wù)合同模板3篇
- 2025至2030年P(guān)MMA亞克力板材項(xiàng)目投資價(jià)值分析報(bào)告
- 2025-2030全球建筑膜產(chǎn)品行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 法語專四四級(jí)詞匯
- 動(dòng)物檢疫技術(shù)-動(dòng)物檢疫的對(duì)象(動(dòng)物防疫與檢疫技術(shù))
- 中考記敘文閱讀
- 《計(jì)算機(jī)應(yīng)用基礎(chǔ)》-Excel-考試復(fù)習(xí)題庫(含答案)
- 產(chǎn)科溝通模板
- 2023-2024學(xué)年四川省成都市小學(xué)數(shù)學(xué)一年級(jí)下冊(cè)期末提升試題
- GB/T 7462-1994表面活性劑發(fā)泡力的測(cè)定改進(jìn)Ross-Miles法
- GB/T 2934-2007聯(lián)運(yùn)通用平托盤主要尺寸及公差
- GB/T 21709.13-2013針灸技術(shù)操作規(guī)范第13部分:芒針
- 2022年青島職業(yè)技術(shù)學(xué)院?jiǎn)握姓Z文考試試題及答案解析
- 急診科進(jìn)修匯報(bào)課件
評(píng)論
0/150
提交評(píng)論