(高清版)GB∕T 38674-2020 信息安全技術(shù) 應(yīng)用軟件安全編程指南_第1頁
(高清版)GB∕T 38674-2020 信息安全技術(shù) 應(yīng)用軟件安全編程指南_第2頁
(高清版)GB∕T 38674-2020 信息安全技術(shù) 應(yīng)用軟件安全編程指南_第3頁
(高清版)GB∕T 38674-2020 信息安全技術(shù) 應(yīng)用軟件安全編程指南_第4頁
(高清版)GB∕T 38674-2020 信息安全技術(shù) 應(yīng)用軟件安全編程指南_第5頁
已閱讀5頁,還剩130頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

信息安全技術(shù)應(yīng)用軟件安全編程指南2020-04-28發(fā)布2020-11-01實(shí)施國家市場監(jiān)督管理總局國家標(biāo)準(zhǔn)化管理委員會GB/T38674—2020 I 1 1 1 1 3 3 4 45.2數(shù)據(jù)加密與保護(hù) 55.3訪問控制 6 8 9 96.2并發(fā)程序安全 6.3函數(shù)調(diào)用安全 6.4異常處理安全 6.5指針安全 6.6代碼生成安全 7資源使用安全 7.1資源管理 7.2內(nèi)存管理 7.3數(shù)據(jù)庫管理 7.4文件管理 7.5網(wǎng)絡(luò)傳輸 8環(huán)境安全 8.1第三方軟件使用安全 8.2開發(fā)環(huán)境安全 8.3運(yùn)行環(huán)境安全 附錄A(資料性附錄)代碼示例 A.2安全功能實(shí)現(xiàn) A.3代碼實(shí)現(xiàn)安全 48A.4資源使用安全 A.5環(huán)境安全 參考文獻(xiàn) I1指導(dǎo)。下列文件對于本文件的應(yīng)用是必不可少的。凡是注日期的引GB/T25069—2010信息安全技術(shù)術(shù)語GB/T25069—2010界定的以及下列術(shù)語和定義適用于本文件。為了便于使用,以下重復(fù)列出了2死鎖deadlock兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因競爭資源或彼此通信而造成的一種阻塞現(xiàn)象。進(jìn)程/線程暫停執(zhí)行過程,等待請求被應(yīng)答的狀態(tài)。一種用于操縱數(shù)據(jù)庫查詢返回的多行結(jié)果集的機(jī)制。敏感數(shù)據(jù)sensitivedata必須受保護(hù)的,其泄露、修改、破壞或丟失會對人或事產(chǎn)生可預(yù)知的損害的信秘密數(shù)據(jù)secretdata為了執(zhí)行特定安全功能策略,只能由授權(quán)用戶或被評對象安全功能知曉的信息。添加變量salt作為單向函數(shù)或加密函數(shù)的二次輸入而加入的隨機(jī)變量,可用于導(dǎo)出口令驗(yàn)證數(shù)據(jù)。由編程人員直接控制的系統(tǒng)部件組成。暫停線程運(yùn)行的操作。導(dǎo)致程序中斷運(yùn)行的一種指令流。系統(tǒng)運(yùn)行中出現(xiàn)的可能導(dǎo)致系統(tǒng)崩潰或者暫停運(yùn)行的非預(yù)期問題。硬編碼hardcode在編碼過程中將可變變量用一個(gè)固定數(shù)值表示。封裝encapsulation將系統(tǒng)功能、一組數(shù)據(jù)和在這些數(shù)據(jù)上的操作隔離在一個(gè)模塊中,并為該模塊提供精確的規(guī)格說明的軟件開發(fā)技術(shù)。3API:應(yīng)用程序編程接口(ApplicationProgramminDNS:域名系統(tǒng)(DomainNameSyFTP:文件傳輸協(xié)議(FileTransferProtocol)HTTP:超級文本傳輸協(xié)議(HyperTextTransferProtocol)IMAP:互聯(lián)網(wǎng)消息訪問協(xié)議(InternetMessagLDAP:輕量目錄訪問協(xié)議(LightweightDirectoryAccesSQL:結(jié)構(gòu)化查詢語言(StructuredQueryLanguage)TLS:傳輸層安全(TransportLayeURL:統(tǒng)一資源定位符(UniformResourceLocator)UTF-8:針對Unicode的可變長度字符編碼(8-bitUnicodeTransformationFormat)XML:可擴(kuò)展置標(biāo)語言(ExtensibleMarkupLanguage)本標(biāo)準(zhǔn)從程序安全和環(huán)境安全兩個(gè)方面提出了提升應(yīng)用軟件安全性的編全管理配置規(guī)范。圖1給出了應(yīng)用軟件編程安全框架。4數(shù)據(jù)庫管理文件管理安全功能實(shí)現(xiàn)代碼實(shí)現(xiàn)安全資源使用安全應(yīng)用軟件需確保對所有輸入到應(yīng)用的數(shù)據(jù)進(jìn)行驗(yàn)證,拒絕接受驗(yàn)證失敗的 b)特別關(guān)注如下場景的數(shù)據(jù)驗(yàn)證:頭以及URL自身傳入?!?yàn)證來自重定向輸入的數(shù)據(jù)。攻擊者可能向重定向的目標(biāo)直接提交惡c)對重要業(yè)務(wù)操作相關(guān)的輸入數(shù)據(jù),驗(yàn)證數(shù)據(jù)的真實(shí)性和完整性,宜驗(yàn)證數(shù)據(jù)發(fā)送方的數(shù)字簽56789e)對每個(gè)重要的行為都記錄日志:g)對日志中的特殊元素進(jìn)行過濾和驗(yàn)證。確保日志記錄中的不可信數(shù)據(jù),不會在查看界面或者相關(guān)的規(guī)范和不規(guī)范的代碼示例參見A.2.4。c)對類的數(shù)據(jù)成員進(jìn)行訪問控制:——當(dāng)類成員需要在聲明該類的包以外被訪問時(shí),使用暴露類成員的封裝器方法監(jiān)視并控制d)避免混用泛型和非泛型的數(shù)據(jù)類型。如為了兼容遺留代碼而混用泛型和非泛型數(shù)據(jù)類型,需f)禁止返回類的私有可變成員的引用。可返回一個(gè)指向內(nèi)部可變成員的防御性副本的引用,從——如果程序邏輯依賴可變變量,則需警惕競態(tài)攻擊??勺冏兞康奶攸c(diǎn)在變化,多次訪問該變量會得到不同的值。如果程序邏輯對可變變——在需要訪問可變變量(或可變的內(nèi)部對象)時(shí),可使用返回可變變量(或可變的內(nèi)部對象)h)禁止復(fù)制或者序列化包含秘密或者其他敏感數(shù)據(jù)的類。i)那些不敏感但是需要維持其他不變性的類,應(yīng)對惡意子類訪問或者操作它們的數(shù)據(jù)及破壞其f)避免在API或與外部交互的接口中暴露那些原本設(shè)計(jì)為僅限內(nèi)部或部分用戶訪問的危險(xiǎn)方g)避免使用在不同版本具有不一致實(shí)現(xiàn)的函數(shù)或方法。相關(guān)的規(guī)范和不規(guī)范的代碼示例參見A.3.3。應(yīng)用軟件需建立完善的異常和錯(cuò)誤處理機(jī)制,確保異常與錯(cuò)誤可以被及時(shí)b)避免在越過執(zhí)行邊界時(shí)拋出異常。c)避免在靜態(tài)對象的構(gòu)造器和線程d)異常處理時(shí)保持?jǐn)?shù)據(jù)的狀態(tài)一相關(guān)的規(guī)范和不規(guī)范的代碼示例參見A.3.4。d)避免將固定地址賦值給指針。e)使用指針時(shí)防止偏移越界。相關(guān)的規(guī)范和不規(guī)范的代碼示例參見A.3.5。c)編譯命令中的宏定義不能存在沖突。g)引用頭文件的路徑不能直接開放。i)同一個(gè)工程中,不同的編譯過程如果使用了同一個(gè)庫的不同版本時(shí),進(jìn)行明確的注釋或提示a)確保系統(tǒng)中的每個(gè)資源具有唯一的標(biāo)識符。——確保應(yīng)用軟件在使用資源后恰當(dāng)?shù)貓?zhí)行臨時(shí)文件或輔助資源的清理,避免清理環(huán)節(jié)不g)合理控制遞歸。g)盡量避免使用不進(jìn)行自變量檢查的、已知存在漏洞的字符串操作函數(shù),如printf、strcat、——宜使用配置合理的單一標(biāo)準(zhǔn)TLS或SSL對連接保護(hù),并支持對敏感文件或非基于c)對重要的配置信息進(jìn)行安全保護(hù)。d)刪除用戶可訪問的源碼中的注釋,避免用戶通過逆向或者直接獲取網(wǎng)頁源代碼方式獲取源代h)建議禁止自動目錄列表功能。如果必須開啟目錄列表功能,則需對目錄下的文件進(jìn)行詳細(xì)檢i)確保軟件運(yùn)行服務(wù)器的系統(tǒng)組件均為相對安全的穩(wěn)定版本,并安裝了相關(guān)的規(guī)范和不規(guī)范的代碼示例參見A.5.3。(資料性附錄)代碼示例A.1概述本附錄給出了第5章~第8章中安全編程指南內(nèi)容的規(guī)范和不規(guī)范的示例,包含詳細(xì)說明和代碼實(shí)例。A.2安全功能實(shí)現(xiàn)A.2.1數(shù)據(jù)清洗A.2.1.1輸入驗(yàn)證針對輸入驗(yàn)證的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.1所示。表A.1針對輸入驗(yàn)證的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系預(yù)防SQL注入預(yù)防XML外部實(shí)體攻擊當(dāng)比較local相關(guān)的數(shù)據(jù)時(shí),指定恰當(dāng)?shù)膌ocal禁止使用被污染的數(shù)據(jù)進(jìn)行進(jìn)程控制禁止使用被污染的數(shù)據(jù)作為緩沖區(qū)A.預(yù)防SQL注入SQL注入是一種數(shù)據(jù)庫攻擊手段。攻擊者通過向應(yīng)用程序提交惡意代碼來改變原SQL語句的含對于預(yù)防SQL注入的情況,示例1給出了不規(guī)范用法(Java語言(Java語言)示例。示例1:publicvoiddoPrivilegedAction(Stringusername,char[]pConnectionconnection=Stringpwd=hashPassword(password);StringsqlString="SELECT*FROMdStatementstmt=connection.createStatement();ResultSetrs=stmt.executeQuery(sql//...}SQL注入漏洞攻擊。示例2:publicvoiddoPrivilegedAction(Stringusername,char[]password)Connectionconnection=Stringpwd=hashPassword(password);if(username,length()}"select*fromdb_usePreparedStatementstmt=connection.prepareStatement(sqlString);}catch(SQLException//...}對于從ZipInputStream安全解壓文件的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1://...publicfinalvoidunzip(Stringfilename)throwsjava,io.IOException{FileInputStreamfis=newFileInputStream(filename);ZipInputStreamzis=newZipInputStream(newBufferedInputStream(fis));while((entry=zis.getNextEntry())!=null){System.out.println("Extrbytedata[]=newbyte[BUFFER];//WritethefilestotFileOutputStreamfos=newFileOutputStream(entry.getName());BufferedOutputStreamdest=newBufferedOutputStream(fos,BUwhile((count=zis.read(data,0,BUFFER))}}}成,或者直至本地資源耗盡為止。staticfinalintTOOBIG=0x6400000;//MaxsizeofunzistaticfinalintTOOMANY=1024;//Max//...privateStringvalidateFilename(throwsjava.io.IOException{StringcanonicalPathFileiD=newFile(intendedDir);StringcanonicalIif(canonicalPath.startsWith(canthrownewIllegalStateException("}publicfinalvoidunzip(Stringfilename)throwsjava.io.IOException{FileInputStreamfis=newFileInputStreaZipInputStreamzis=newZipInputStream(newBufferedInputStreamwhile((entry=zis.getNextEntry()System.out.println("Extrbytedata[]=newbyte[BUFFER];Stringname=validateFilename(entry.getName(),".");System.out.printIn("Creatingdirectory"}FileOutputStreamfos=newFileOutputStream(name);BufferedOutputStreamdest=newBufferedOutputStream(fos,BUFFER);while(total+BUFFER<=TOOBIG&.&.(count=zis.read(data,0,BUFFER))!=-1){}thrownewIllegalStateException("Toomanyfilestounzip.");thrownewIllegalStateException("Filebeingunzippedistoobig.");}}}可以偽造ZIP文檔中未壓縮的文件的大小。最后,代碼還計(jì)算壓縮包中文件條目的數(shù)量,如果超過對于凈化傳遞給Runtime.exec()方法的非受信數(shù)據(jù)的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1(Windows):publicstaticvoidmain(String[]args)throwsStringdir=System.getPropertRuntimert=Runtime.getRuProcessproc=rt.exec("cmd.exe/Cdir"+dir);System.out.println("processerror:"+}InputStreamin=(result==0)?proc.getInputStream():proc.getErrorStreamwhile((c=in.read())!=}}該代碼示例使用dir命令列出目錄列表。這是通過Runtime.exec()方法調(diào)用Windows的dir命令來實(shí)現(xiàn)的。因?yàn)镽untime.exec()方法接受源于運(yùn)行環(huán)境的未經(jīng)凈化的數(shù)據(jù),所以這些代碼會引起命令注入攻擊。攻擊者可以通過以下命令利用該程序:java-Ddir='dummy&.echobad'Java該命令實(shí)際上執(zhí)行的是兩條命令:第一條命令會列出并不存在的dummy文件夾,并且在控制臺上輸出bad。if(!Pattern.matches("[0-9A-Za-z@.//...}這個(gè)符合規(guī)范的代碼實(shí)例會對非受信的用戶輸入進(jìn)行凈化,只允許白名單中的字符出現(xiàn)在參數(shù)中,并傳給Runtime.exec()方法,其他所有的字符都會被排除掉。A.不要信任隱藏字段的內(nèi)容HTML允許web表單中的字段可見或隱藏。隱藏字段向web服務(wù)器提供值,但不能被用戶修改其內(nèi)容。但是,攻擊者仍然可以通過特殊方式來修改隱藏字段。對于不信任隱藏字段的內(nèi)容的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。response,setContentType("text/hPrintWriterout=responseStringvisible=request.gStringhidden=request.gout.println("VisiblePaout.println(sanitizeout.println("<br>HiddenPaout.println("<inputtype=teout.println("<inputtype=hiddenname=hiddenvalue=\abenignvalue\>");out.println("<inputtype=submit)"}}//...}上面代碼演示了一個(gè)servlet,它接受一個(gè)可見的字段和一個(gè)隱藏的字段,并將其返回給用戶。在傳遞給瀏覽器之前,可見的參數(shù)是經(jīng)過驗(yàn)證處理的,但是隱藏的字段沒有驗(yàn)證。當(dāng)輸入?yún)?shù)paraml時(shí),web頁面將顯示以下內(nèi)容:VisibleParameter:paramlHiddenParameter:abenignvalue但是,攻擊者可以通過在URL中編碼來為隱藏參數(shù)提供一個(gè)值,如下:http://localhost:8080/sample/SampleServlet?visible=dummy&-hidden=%3Cfonred%3ESurprise%3C/font%3當(dāng)這個(gè)URL被提供給瀏覽器時(shí),瀏覽器會顯示:HiddenParameter:response.setContentType("text/hPrintWriterout=responseStringvisible=request.getParStringhidden=request.gout.printIn("VisiblePaout.printIn(sanitizeout.println("<br>HiddenPaout.println(sanitize(hidden));//Hiddenvariablesanitizedout.println("<inputtype=teout.println("<inputtype=hiddenname=hiddenvalue=\abenignvalue\》");out.printIn("<inputtyp}}//...}上面代碼片段對隱藏字段進(jìn)行凈化,因此,當(dāng)惡意URL進(jìn)入瀏覽器時(shí),servlet產(chǎn)生以下內(nèi)容:HiddenParameter:<fontcolor=red>如果用戶有能力使用結(jié)構(gòu)化XML文檔作為輸入,那么他能夠通過在數(shù)據(jù)字段中插入XML標(biāo)簽來重寫這個(gè)XML文檔的內(nèi)容。XML解析器會將這些標(biāo)簽按照正常標(biāo)簽進(jìn)行解析。下面是一段在線商店的XML代碼,主要用于查詢后臺數(shù)據(jù)庫。惡意用戶可以在<quantity>元素中輸入以下字符串:1</quantity><price>1.0</price><quantity>1會生成以下的XML文檔:通過使用簡單的API解析器(org.xml.saxandjavax.xml.parsers.SAXParser)可以解析該XML文件,如果解析XML的代碼獲取的是最后一個(gè)元素<price>的值,那么商品價(jià)格就被設(shè)置為1.0。對于預(yù)防XML注入的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。StringxmlString="<item)\n(descriptio}上面的代碼樣例中,一個(gè)方法簡單的使用了字符串拼接來創(chuàng)建一個(gè)XML查詢,然后將其發(fā)送到服務(wù)器。在這時(shí)就有可能出現(xiàn)XML注入問題,因?yàn)檫@個(gè)方法沒有進(jìn)行任何輸入驗(yàn)證。當(dāng)XML可能已經(jīng)載入還未處理的輸入數(shù)據(jù)時(shí),一般情況下使用XML模板或者DTD驗(yàn)證XML。如果還沒有創(chuàng)建這樣的XML字符串,那么應(yīng)在創(chuàng)建XML之前處理輸入,這種方式性能較高。//WriteXMLstringonlyifquantityisanunsignedinteger(count).intcount=Integer.parseUnStringxmlString="<item)\n(description)W十"<price>500</price)\n"+"<quantity)"十count+"</quantity)</item)";}}代碼的解決方案是驗(yàn)證quantity是一個(gè)無符號整數(shù)。A.預(yù)防XML外部實(shí)體攻擊XML文檔可以從一個(gè)很小的邏輯塊(實(shí)體)開始動態(tài)構(gòu)建。實(shí)體可以是內(nèi)部的、外部的或者基于參數(shù)的。外部實(shí)體運(yùn)行是將外部文件中的XML包含進(jìn)來。攻擊者可以通過操作實(shí)例的URI,使其指向特定的在當(dāng)前文件系統(tǒng)中保存的文件,從而造成拒絕服務(wù)或程序崩潰,比如:指定/dev/random或者/dev/tty作為輸入的URI,這可能造成永久阻塞程序或者程序崩潰。對于預(yù)防XML外部實(shí)體攻擊的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。SAXParsersaxParser=factorsaxParser.parse(inStream,de}System.err.println("Malforme}}會嘗試訪問在SYSTEM屬性中標(biāo)識的URL,這意味著它將讀取一個(gè)本地的/dev/try文件的內(nèi)容。在者可以使用這一類的惡意XML文件來導(dǎo)致系統(tǒng)掛起。使用EntityResolver方案來防止XML外部實(shí)體注入。示例2:publicInputSourceresolveEntity(Stringpublicld,String//CheckforknowngoodentitStringentityPath="file:/Usersif(systemld.equals(entiSystem.out.println("Resolvingentity:"+publicld+""+systemld);returnnewInputSource(en//Disallowunknownentitiesbyreturningablankpath}針對不規(guī)范的代碼示例的解決方案是,定義一個(gè)CustomResolver類,這個(gè)類實(shí)現(xiàn)了org.xEntityResolver接口。它可以讓SAX應(yīng)用定制對外部實(shí)體的處理。這個(gè)定制的處理器使用的是一個(gè)法會返回一個(gè)空的InputSource對象。setEntityResolver()方法可以將對應(yīng)的SAX驅(qū)動實(shí)例注義解析器返回的空的InputStream對象會拋出.MalformedURLException異常。需要注意的是,應(yīng)創(chuàng)建一個(gè)XMLReader對象,以便通過這個(gè)對象來設(shè)置自定義的實(shí)體解析器。privatestaticvoidreceiveXMLStream(InputStreaminStream,DefaultHandlerdefathrowsParserConfigurationException,SAXException,IOException{SAXParserFactoryfactory=SAXParserFactory.newInstance();SAXParsersaxParser=factory.newSAXParser();//TosettheEntityResolver,anXMLreaderneedstobecreaXMLReaderreader=saxParser.getXMLReadreader.setEntityResolver(newCustomResolver());reader,setErrorHandler(defaultHand}}當(dāng)locale沒有明確指定的時(shí)候,使用locale相關(guān)的方法處理與local相關(guān)的數(shù)據(jù)會產(chǎn)生意想不到的結(jié)果。編程語言標(biāo)識符、協(xié)議關(guān)鍵字以及HTML標(biāo)簽通常會指定Locale.ENGLISH作為一個(gè)特定的locale。在不同的locale環(huán)境中運(yùn)行程序可能會導(dǎo)致意外的程序行為,甚至允許攻擊者繞過輸入過濾publicclassExample{publicstaticvoidmain(String[]argsSystem.out.println("Titl}在英文locale環(huán)境下:大寫形式也有一個(gè)點(diǎn)(I),沒有點(diǎn)的1大寫形式?jīng)]有點(diǎn)(I)。在土耳其locale(API2006)會產(chǎn)生下面預(yù)則可以安全地依賴于默認(rèn)的locale設(shè)置。對于指定恰當(dāng)?shù)膌ocal的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法//Processtag}在英語locale中"script"大寫轉(zhuǎn)換成"SCRIPT",而在土耳其locale環(huán)境中,將"script"大寫轉(zhuǎn)換}擊(denial-of-service(對于污點(diǎn)數(shù)據(jù)作為循環(huán)邊界的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出示例1:}示例2:for(i=0;i(num;i+十){}}要注意進(jìn)行本機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序之間的相互轉(zhuǎn)換。在調(diào)用recv或read函數(shù)從外部系統(tǒng)接收數(shù)據(jù)外的行為。對于從外部系統(tǒng)接收的數(shù)據(jù)應(yīng)該轉(zhuǎn)換為本地字節(jié)序的情況,示例1給出了不規(guī)范用法(C/語言)示例。示例2給出了規(guī)范用法(C/C+十語言)示例。示例1:recv(s,&.u,sizeof(u)}示例2:recv(ss,&-uu,sizeof(uu)}A.1注意被污染的內(nèi)存分配對于注意被污染的內(nèi)存分配的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C+十語言)示例。示例1:}示例2:#defineMAX_BUFFER_SI}在如上示例中,使用變量size前,對其進(jìn)行了有效的長度驗(yàn)證,確保其大小不會超過512,從而避免了過大長度的內(nèi)存分配。A.2禁止使用被污染的數(shù)據(jù)進(jìn)行操縱設(shè)置在調(diào)用某些對系統(tǒng)進(jìn)行配置的庫函數(shù)、API時(shí),直接使用污點(diǎn)數(shù)據(jù)作為相關(guān)的配置參數(shù),會為惡意攻擊者提供篡改操作系統(tǒng)的可能性,進(jìn)而對操作系統(tǒng)造成破壞。對于禁止使用被污染的數(shù)據(jù)進(jìn)行操縱設(shè)置的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C+十語言)示例。示例1:voidf(LPCTSTRlpFileName,DWORDdwFileAttribuSetFileAttributes(lpFileName,}示例2:SetFileAttributes(lpFileName,dwFileAt}}示例1:voidf(LPCTSTRIpTemplateDirectory,LPLPSECURITY_ATTRIBUTESIpSecuriscanf("%s",lpTemplaCreateDirectoryEx(lpTemplateDirectory,lpNewDirectory,IpSecur}用明確的固定的數(shù)據(jù)來進(jìn)行路徑操作,如果路徑操作的參數(shù),確實(shí)需要從外界獲取,在這種情況下,需要注意設(shè)計(jì)并實(shí)現(xiàn)完備的驗(yàn)證機(jī)制。示例2:voidf(LPCTSTRIpTemplateDirectory,LPLPSECURITY_ATTRIBUTESIpSecuriCreateDirectoryEx("C:/Temp",IpNewDirectory,IpSecuri}示例3:boolisDirectoryValid(LPCTSTRIpTemplateDirectory){//validatelpTemplateDire}voidf(LPCTSTRIpTemplateDirectory,LPCTSTRIpNewDirectory,LPSECURITY_ATTRIBUTESIpSecuriscanf("%s",IpTemplaif(!isDirectoryValid(lpTemplateDCreateDirectoryEx(lpTemplateDirectory,IpNewDirectory,IpSecur}A.4禁止使用被污染的數(shù)據(jù)進(jìn)行進(jìn)程控制示例2給出了規(guī)范用法(C/C+十語言)示例。示例1:}在如上示例中,函數(shù)LoadLibrary()加載庫的參數(shù)為污點(diǎn)數(shù)據(jù)。用明確的固定的數(shù)據(jù)來進(jìn)行動態(tài)庫加載,如果加載動態(tài)庫的參數(shù),確實(shí)需要從外界獲取,在這種情況下,需要注意設(shè)計(jì)并實(shí)現(xiàn)完備的驗(yàn)證機(jī)制。示例2:lpFileName=CheckArgStr(lpFileName);}A.5禁止使用被污染的數(shù)據(jù)作為緩沖區(qū)長度很多庫函數(shù)、API在對緩沖區(qū)進(jìn)行操作的時(shí)候,需要通過一個(gè)整型參數(shù)來指定這個(gè)緩沖區(qū)的長度限制。直接將污點(diǎn)數(shù)據(jù)作為長度限制參數(shù),可能會造成緩沖區(qū)溢出。對于禁止使用被污染的數(shù)據(jù)作為緩沖區(qū)長度的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C++語言)示例。示例1:}在如上示例中,函數(shù)memcpy()指定復(fù)制內(nèi)存長度的參數(shù)為污點(diǎn)數(shù)據(jù)。示例2:}如上示例中,復(fù)制內(nèi)存的長度參數(shù)count沒有被污染。但在調(diào)用該函數(shù)前,仍需要對其長度進(jìn)行驗(yàn)證,以確保該長度值不會超過目的緩沖區(qū)的長度。A.6禁止使用被污染的數(shù)據(jù)作為緩沖區(qū)將被污染的數(shù)據(jù)直接作為參數(shù)傳遞給對緩沖區(qū)進(jìn)行處理的庫函數(shù)、API可能會造成緩沖區(qū)溢出。對于禁止使用被污染的數(shù)據(jù)作為緩沖區(qū)的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C++語言)示例。示例1:_stprintf(buffer,"%s",str);}在如上示例中,函數(shù)_stprintf()通過字符串打印的方式,將str復(fù)制到目的緩沖區(qū)buffer中。由于源字符串str是污點(diǎn)數(shù)據(jù),其長度可能會超過目的緩沖區(qū)buffer的長度,該復(fù)制動作,可能會導(dǎo)致緩沖區(qū)溢出。示例2:_stprintf(buffer,"%s",str);如上示例中,str沒有被污染。但在調(diào)用該函數(shù)前,仍需要對其長度進(jìn)行驗(yàn)證,以確保該長度值不會超過目的緩沖區(qū)的長度。A.2.1.2輸出凈化A.概述針對輸出凈化的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.2所示。表A.2針對輸出凈化的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系示例語言預(yù)防基于DOM的XSS向外部系統(tǒng)傳輸數(shù)據(jù)前應(yīng)該轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序A.預(yù)防反射型XSS應(yīng)用程序通過Web請求獲取不可信賴的數(shù)據(jù),在未檢驗(yàn)數(shù)據(jù)是否存在惡意代碼的情況下,便將其傳送給了Web用戶,應(yīng)用程序?qū)⒁子谑艿椒瓷湫蚗SS攻擊。對于預(yù)防反射型XSS的情況,示例給出了不規(guī)范用法(Java語言)示例。<%Stringname=request.getParameter("username");%>如果name里有包含惡意代碼,那么Web瀏覽器就會像顯示HTTP響應(yīng)那樣執(zhí)行該代碼,應(yīng)用程序?qū)⑹艿椒瓷湫蚗SS攻擊。為了避免反射型XSS攻擊,建議采用以下方式進(jìn)行防御:cript等)進(jìn)行過濾。b)根據(jù)數(shù)據(jù)將要置于HTML上下文中的不同位置(HTML標(biāo)簽、HTML屬性、JavaScript腳本、CSS、URL),對所有不可信數(shù)據(jù)進(jìn)行恰當(dāng)?shù)妮敵鼍幋a。例如:采用OWASPESAPI對數(shù)據(jù)輸出HTML上下文中不同位置,編碼方法如下。//HTMLattributeencc)設(shè)置HttpOnly屬性,避免攻擊者利用跨站腳本漏洞進(jìn)行Cookie劫持攻擊。在JavaEE中,給Cookie添加HttpOnly的代碼如下:response.setHeader("Set-Cookie","cookiename=cookievalue;path=/;Domain=domainvaule;Max-age=A.預(yù)防基于DOM的XSSDOM型XSS從效果上來說也屬于反射型XSS,由于形成的原因比較特殊所以進(jìn)行單獨(dú)劃分。在網(wǎng)站頁面中有許多頁面的元素,當(dāng)頁面到達(dá)瀏覽器時(shí)瀏覽器會為頁面創(chuàng)建一個(gè)頂級的Documentobject文檔對象,接著生成各個(gè)子文檔對象,每個(gè)頁面元素對應(yīng)一個(gè)文檔對象,每個(gè)文檔對象包含屬性、方法和事件??梢酝ㄟ^JS腳本對文檔對象進(jìn)行編輯從而修改頁面的元素。也就是說,客戶端的腳本程序可以通過DOM來動態(tài)修改頁面內(nèi)容,從客戶端獲取DOM中的數(shù)據(jù)并在本地執(zhí)行。當(dāng)應(yīng)用程序的客戶端代碼將不受信的參數(shù)直接用于動態(tài)更新頁面的DOM節(jié)點(diǎn),應(yīng)用程序?qū)⒁子谑艿交贒OM的XSS攻擊。對于預(yù)防基于DOM的XSS的情況,示例給出了不規(guī)范用法(javascript語言)示例。varstr=document.getElementBdocument.getElementByld("test"),innerHTML="(ahref="+str+")testLink</a>";}<inputtype="text"id="text"value=""/><inputtype="button"value="write"onclick在這里,'write'按鈕的onclick事件調(diào)用了test()方法,而該函數(shù)直接引用用戶輸入的值修改頁面b)與預(yù)防反射型XSS相同,根據(jù)數(shù)據(jù)將要置于HTML上下文中的不同位置(HTML標(biāo)簽、A.預(yù)防存儲型XSS<%...ResultSetrs=stmt.executeQuery("select*fromuserswhaddress=rs.getString("}如果name的值是由用戶提供的,且存入數(shù)據(jù)庫時(shí)沒有進(jìn)行合理的校驗(yàn),那么攻擊者就可以利用上b)與預(yù)防反射型XSS相同,根據(jù)數(shù)據(jù)將要置于HTML上下文中的不同位置(HTMLA.向外部系統(tǒng)傳輸數(shù)據(jù)前應(yīng)該轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序要注意進(jìn)行本機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序之間的相互轉(zhuǎn)換。在調(diào)用se對于向外部系統(tǒng)傳輸數(shù)據(jù)前應(yīng)該轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C++語言)示例。voidbadl(ints,shortx){send(s,&u,sizeof(u),0在調(diào)用send函數(shù)之前,沒有調(diào)用htons或htonl函voidgoodl(ints,shoA.2.2數(shù)據(jù)加密與保護(hù)A.2.2.1加密規(guī)范A.概述表A.3針對加密規(guī)范的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系A(chǔ).生成強(qiáng)隨機(jī)數(shù)JavaAPI提供了java.util.Random類來實(shí)現(xiàn)PRNG。這個(gè)PRNG是可移植和可重復(fù)的。因此,如果兩個(gè)java.util.Random類的實(shí)例使用了相同的種子,會在所有的Java實(shí)現(xiàn)中生成相同的數(shù)值序列。于當(dāng)前的時(shí)刻獲取。攻擊者可以通過對有漏洞的目標(biāo)系統(tǒng)做探查而獲取因此,java.util.Random不能在安全應(yīng)用或者在需對敏感數(shù)據(jù)進(jìn)行保護(hù)的場合使用(如:密碼學(xué)),對于生成強(qiáng)隨機(jī)數(shù)的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法示例1:importjava.util.Random;//...Randomnumber=newRandom(123L);intn=number.nextInt(21);}示例2:importjava.security.SecureRandom;importjava.security.NoSuchAlgorithmException;//...publicstaticvoidmain(StringargSecureRandomnumber=SecureRandom.getInstance("SHA1PRNG");//Generate20integerSystem.out.printIn(numbe}}A.避免使用不安全的哈希算法示例1:byte[]b=str.getBytesMessageDigestmmd=MessageDigest.getInstance("以上代碼片段中,采用MD5算法來保證數(shù)據(jù)的完整性。byte[]b=str.getBytesmd=MessageDigest.getInstance("SHA-}在安全性要求較高的系統(tǒng)中,應(yīng)采用散列值>=224比特的SHA系列算法(如SHA-224、SHA-256、SHA-384和SHA-512)來保證敏感數(shù)據(jù)的完整性。以上代碼片段中,使用SHA-256算法取代MD5算法保證數(shù)據(jù)完整性。A.密鑰長度應(yīng)該足夠長加密算法中使用的密鑰長度較短,會降低系統(tǒng)安全。對于密鑰長度應(yīng)足夠長的情況,示例給出了不規(guī)范用法(Java語言)示例。PrivateKeyprivateKey=(RSAPrivateKey)keyPair.getbyte[]publicKeyData=publicKey.getEncodbyte[]privateKeyData=privateKey.getEncod以上代碼片段中,KeyPairGenerator使用RSA加密算法,長度為1024位。對于對稱加密算法,建議使用長度大于或等于128位的密鑰。對于非對稱加密算法(如RSA),建議使用長度大于或等于2048位的密鑰。A.避免使用不安全的加密算法在安全性要求較高的系統(tǒng)中,使用不安全的加密算法(如DES、3DES、RC4、RC5等),將無法保證敏感數(shù)據(jù)的保密性。對于避免使用不安全的加密算法的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。BufferedReaderbufread2=nInputStreamReaderinread2=null;inread2=newInputStreamReader(bufread2=newBufferedReader(inStringstr=bufread2./*FLAW:Insecurecryptographicalgorithm(DES)*/SecretKeykey=KeyGenerator.getInstance("DES").des.,init(Cipher.ENCRYPT_byte[]enc_str=des.doFinal(str.getBytesIO.writeLine(IO.toHex(enlog_bsnk,warning("Err}以上代碼片段中,采用DES對數(shù)據(jù)進(jìn)行加密。在安全性要求較高的系統(tǒng)中,建議使用安全的加密算法(如AES、RSA)對敏感數(shù)據(jù)進(jìn)行加密。示例2:BufferedReaderbufread2=null;InputStreamReaderinrinread2=newInputStreamReader(Sbufread2=newBufferedReader(inread2);/*FIX:SecurecryptographicalgoritCipheraes=Cipher.getInstance("AES");KeyGeneratorkg=KeyGenerator.getInstance("AES");SecretKeykey=kg.aes.init(Cipher.ENCRYPTbyte[]enc_str=aes.doFinal(str.getBytes());I0.writeLine(IO.toHex(enlog_gsnk.warning("Err}以上代碼片段中,使用AES取代DES保證數(shù)據(jù)完整性。A.避免使用不安全的操作模式塊密碼又稱為分組加密,一次加密明文中的一個(gè)塊。將明文按一定的位長分組,明文組經(jīng)過加密運(yùn)算得到密文組,密文組經(jīng)過解密運(yùn)算(加密運(yùn)算的逆運(yùn)算),還原成明文組。這種加密算法共有四種操作模式用于描述如何重復(fù)地應(yīng)用密碼的單塊操作來安全的轉(zhuǎn)換大于塊的數(shù)據(jù)量,分別是電子代碼(ECB)、密碼塊鏈(CBC)、密碼反饋(CFB)以及輸出反饋(OFB)。其中ECB模式下相同的明文塊總是會得到相同的密文,故不能抵擋回放攻擊,而CBC模式則沒有這個(gè)缺陷。對于避免使用不安全的操作模式的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。Ciphercipher=Cipher.getInstance("AES/ECB/PKCS以上代碼將AES密碼用于ECB模式。加密大于塊的數(shù)據(jù)時(shí),需要注意避免使用ECB模式。由于CBC模式不會對相同的明文塊生成相同的密文塊,所以CBC模式更好。然而,CBC模式效率較低,并且在和SSL一起使用時(shí)會造成嚴(yán)重風(fēng)險(xiǎn)??梢愿挠肅CM(CounterwithCBC-MAC)模式,如果更注重性能,在可用的情況下則使用GCMCiphercipher=Cipher.get以上代碼將AES密碼用于CBC模式。當(dāng)程序中使用硬編碼加密密匙時(shí),所有項(xiàng)目開發(fā)人員都可以查看該密匙,甚至如果攻擊者能夠獲取程序class文件,可通過反編譯得到密匙,硬編碼加密密匙會大大降低系統(tǒng)安全性。對于避免使用硬編碼密匙的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。byte[]keyBytes=encryptionKey.getByte上述代碼使用硬編碼加密密鑰執(zhí)行AES加密。程序應(yīng)采用不小于8個(gè)字節(jié)的隨機(jī)生成的字符串作為密匙。SecretKeysecretKey=kbyte[]keyBytes=secretKey.getEn上述代碼使用KeyGenerator來生成密匙。A.考慮對函數(shù)指針進(jìn)行加密在某些情況下,攻擊者可以通過修改內(nèi)存甚至函數(shù)指針來執(zhí)行任意代碼。為了減少這類攻擊的影響,函數(shù)指針應(yīng)該在運(yùn)行時(shí)進(jìn)行加密,并在執(zhí)行程序時(shí)才進(jìn)行解密。對于考慮對函數(shù)指針進(jìn)行加密的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C+十語言)示例。int(*log_fn)(const這個(gè)不規(guī)范的代碼示例將printf()函數(shù)賦給log_fn函數(shù)指針,并且它能夠分配在棧的數(shù)據(jù)段里。如果允許攻擊者修改log_fn函數(shù)指針,則將出現(xiàn)可攻擊點(diǎn),例如緩沖區(qū)溢出或者內(nèi)存任意寫入。攻擊者可能用本地的任意函數(shù)覆蓋printf的值。voidlog_fn=EncodePointer(printf);int(*fn)(constchar,..)=(int(*)(constMicrosoftWindows提供了EncodePointer()和DecodePointer()函數(shù)對指針進(jìn)行加密和解密,確保只對給定的程序調(diào)用。注意,DecodePointer()沒有返回成功或者失敗。如果攻擊者能夠重寫指針包括log_fn,那么將會返回非法的指針并且會導(dǎo)致程序崩潰。但是,與給攻擊者提供執(zhí)行任意代碼的能力相比,這種情況的安全風(fēng)險(xiǎn)更低。A.2.2.2數(shù)據(jù)保護(hù)針對數(shù)據(jù)保護(hù)的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.4所示。表A.4針對數(shù)據(jù)保護(hù)的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系不要硬編碼敏感信息A.避免在注釋中保留密碼應(yīng)用程序注釋中保留密碼等敏感信息,將使敏感信息對任何能夠獲取到該文件的人員可見。應(yīng)用程序注釋中不可保留密碼等敏感信息。A.不要硬編碼敏感信息硬編碼如密碼、服務(wù)器IP地址、加密密匙這樣的敏感信息,會將信息暴露給攻擊者。任何一個(gè)可以訪問類文件的人都可以對其進(jìn)行反編譯,然后得到敏感信息。因此,程序不能對敏感信息進(jìn)行硬編碼。對敏感信息進(jìn)行硬編碼會使代碼管理變得更復(fù)雜。例如,在一個(gè)已部署的程序中,改變其硬編碼密碼需要發(fā)布補(bǔ)丁。對敏感數(shù)據(jù)進(jìn)行硬編碼會向攻擊者泄露信息。對于不要硬編碼敏感信息的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1:publicstaticvoidmai//...示例2:publicstaticvoidmain(String[]args)throwsIOException{BufferedReaderbr=newBufferedReader(newIFileInputStream("serveripaddress.t//returnsthenumberofbytesreadintn=br.read(ipAddress);//ValidateserverIPaddressfor(inti=n-1;i}}A.2.3訪問控制A.2.3.1身份鑒別A.概述表A.5針對身份鑒別的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系示例語言A.避免使用DNS名稱作為安全性的依據(jù)對避免使用DNS名稱作為安全性的依據(jù)的情況,示例給出了不規(guī)范用法(Java語言)示例。InetAddressinetAddress=InetAddress.getB}以上代碼片段中,如果發(fā)生DNS欺騙,會繞過安全驗(yàn)證。不要依賴DNS名稱進(jìn)行安全認(rèn)證。A.SSL連接時(shí)要進(jìn)行服務(wù)器身份驗(yàn)證當(dāng)進(jìn)行SSL連接時(shí),服務(wù)器身份驗(yàn)證處于禁用狀態(tài)。在某些使用SSL連接的庫中,默認(rèn)情況下不驗(yàn)證服務(wù)器證書。這相當(dāng)于信任所有證書。對SSL連接時(shí)要進(jìn)行服務(wù)器身份驗(yàn)證的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。上述代碼片段沒有明確地驗(yàn)證服務(wù)器證書。當(dāng)嘗試連接到:25時(shí),此應(yīng)用程序?qū)㈦S時(shí)接受頒發(fā)給“”的證書。此時(shí),當(dāng)服務(wù)器被黑客攻擊發(fā)生SSL連接中斷時(shí),應(yīng)用程序可能會泄露用戶敏感信息。當(dāng)進(jìn)行SSL連接時(shí),需要注意進(jìn)行服務(wù)器驗(yàn)證檢查。根據(jù)所使用的庫,驗(yàn)證服務(wù)器身份并建立安全的SSL連接。上述代碼示例中,明確驗(yàn)證服務(wù)器證書。A.保證必要加密步驟在生成加密簽名過程中,代碼缺少必要的步驟,會削弱所生成簽名的強(qiáng)度。對于保證必要加密步驟的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1:Signaturesignetcheck=Signature.getI//signetcheck.update(message);//lackofnecessarysteps上述代碼片段中,缺少update的調(diào)用,導(dǎo)致創(chuàng)建不基于任何數(shù)據(jù)的簽名。在生成加密簽名過程中,執(zhí)行所有必需的步驟,確保不會削弱簽名的強(qiáng)度。示例2:Signaturesignetcheck=Signature.getI上述代碼片段中,添加update的調(diào)用。A.2.3.2口令安全A.概述針對口令安全的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.6所示。表A.6針對口令安全的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系示例語言A.避免使用null密碼null密碼會削弱系統(tǒng)的安全性,甚至引起系統(tǒng)異常。對于避免使用null密碼的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1:conn=DriverManager.getConnection(url,"r上述代碼中采用硬編碼密碼獲取數(shù)據(jù)庫連接。程序中不可采用null密碼,程序所需密碼應(yīng)從配置文件中獲取加密的密碼值。示例2:Stringpassword=getEconn=DriverManager.getConnection(url,use上述代碼中采用經(jīng)過加密的密碼值來獲取數(shù)據(jù)庫連接。A.避免使用空密碼程序中使用了空的密碼值,系統(tǒng)安全性將會受到威脅。對于避免使用空密碼的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。conn=DriverManager.getConnection(url,上述代碼中采用空密碼獲取數(shù)據(jù)庫連接。程序中所需密碼應(yīng)從配置文件中獲取經(jīng)過加密的密碼值。conn=DriverManager.getConnection(url,use上述代碼中采用經(jīng)過加密的密碼值來獲取數(shù)據(jù)庫連接。A.避免使用明文密碼程序中使用了來自文件或者網(wǎng)絡(luò)的未進(jìn)行加密的明文密碼。對于避免使用明文密碼的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。Stringpassword=request.getParadBConnection=DriverManager.getConnection(url,na上述代碼片段中,使用來自網(wǎng)絡(luò)的明文密碼用于獲取connection。明文密碼會降低系統(tǒng)安全性,應(yīng)對程序中使用的密碼值進(jìn)行加密。SecretKeySpecsecretKeySpec=newSecretKStringdecryptedPassword=newString(aesCipher.doFdBConnection=DriverManager.getConnection(url,name,decryp上述代碼片段中,獲取connection時(shí)使用已經(jīng)加密的密碼。A.避免使用弱加密算法保護(hù)密碼程序采用簡單的編碼(如base64)或弱哈希算法(如MD5、SHA-1)對密碼進(jìn)行加密不能有效地保護(hù)密碼。應(yīng)用程序需要注意對密碼進(jìn)行恰當(dāng)?shù)墓_\(yùn)算(如SHA-224、SHA-256、SHA-384和SHA-512)進(jìn)行保護(hù)。A.2.3.3權(quán)限管理A.概述針對權(quán)限管理的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.7所示。表A.7針對權(quán)限管理的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系避免越權(quán)訪問A.避免越權(quán)訪問多用戶系統(tǒng)中的文件通常為某一特定用戶所有,文件所有者會指定系統(tǒng)中的用戶可以訪問這些文件的內(nèi)容。當(dāng)一個(gè)程序使用不充分的限制性的訪問權(quán)限創(chuàng)建文件時(shí),攻擊者可以在程序修改權(quán)限之前讀取或者修改這些文件。如果允許用戶輸入直接更改文件權(quán)限,則攻擊者將能夠訪問其他受保護(hù)的系統(tǒng)資源。對于避免越權(quán)訪問的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。StringpermissionMask=System.getPropPathpath=testFile.toPath();以上代碼使用來自系統(tǒng)屬性的參數(shù)作為默認(rèn)的權(quán)限代碼。但是系統(tǒng)屬性中的值未必是可信的,如果系統(tǒng)屬性中的值為攻擊者可控,則可以使用該程序獲得其所處理文件的訪問權(quán)限。如果程序還易受路徑篡改攻擊,那么攻擊者可能會利用這一漏洞訪問系統(tǒng)中的任意文件。StringpermissionMask=System.getProPathpath=testFile,toPath();String[]validPermissions={"r—-","r--r----—"};}上述代碼可以通過允許用戶設(shè)置文件權(quán)限來防止此類文件權(quán)限操縱。如果必須確保用戶擁有能夠設(shè)置文件的權(quán)限,則可以采用一種間接方式,即創(chuàng)建一個(gè)允許用戶進(jìn)行指定的合法文件權(quán)限列表,并且僅允許用戶從列表中進(jìn)行選擇。通過這種方式,用戶提供的輸入將不會直接更改文件權(quán)限。某些函數(shù)只能被特定的權(quán)限或者擁有特定權(quán)限的用戶或用戶組(例如本地管理員等)調(diào)用執(zhí)行。某些函數(shù)會對同時(shí)訪問的用戶數(shù)量進(jìn)行限制,例如獲取系統(tǒng)資源的相關(guān)函數(shù)。在很多網(wǎng)絡(luò)服務(wù)程序中,超級管理員用戶權(quán)限均可以開啟TCP或UDP端口,而一般的用戶則不具備該權(quán)限。盡管在某些特定的情況下可能需要臨時(shí)提升權(quán)限來進(jìn)行相應(yīng)的操作,然而很多程序在獲取了相關(guān)的權(quán)限并執(zhí)行了相應(yīng)的操作后,并沒有將其及時(shí)降低到級別較低的原初始權(quán)限,而是在較高級別的權(quán)限為降低權(quán)限,進(jìn)程需要為權(quán)限較低的用戶,有效的設(shè)定用戶和組的ID。通過調(diào)用函數(shù)seteuid()和setegid()能夠臨時(shí)或長期的更改用戶權(quán)限。如果需要提升程序權(quán)限以執(zhí)行高權(quán)限操作,例如打開私有文件等,程序可以通過函數(shù)seteuid()來獲取權(quán)限。函數(shù)seteuid()允許可執(zhí)行文件以用戶角色執(zhí)行管理員權(quán)限的操作。然而,在完成高權(quán)限的操作動作后,程序不會自己立刻降低回到較低的用戶權(quán)限。為降低未授權(quán)的代碼獲得控制權(quán)的可能性,需要注意讓程序在其最小權(quán)限內(nèi)運(yùn)行。應(yīng)用程序的提升權(quán)限操作,很可能會將系統(tǒng)開放給攻擊者。程序提升權(quán)限的時(shí)間,應(yīng)被設(shè)計(jì)為盡可能的短,并將潛在的安全隱患告知用戶。A.避免不當(dāng)?shù)腤indowsApi權(quán)限參數(shù)配置很多的MicrosoftWindows函數(shù)都存在危險(xiǎn)宏參數(shù)的問題,在調(diào)用相關(guān)函數(shù)時(shí),將不安全的宏作為參數(shù),將會允許惡意攻擊者訪問注冊表或者運(yùn)行任意指令。對于避免不當(dāng)?shù)腤indowsApi權(quán)限參數(shù)配置的情況,示例1給出了不規(guī)范用法(C/C++語言)示例。示例2給出了規(guī)范用法(C/C++語言)示例。LONGfoo(LPCTSTRIpSubKey,DWORDulOptionsreturnRegOpenKeyEx(HKEY_USERS,lpSubKey,ulOptions,samDesired,phk}上述示例中,在危險(xiǎn)函數(shù)RegOpenKeyEx中使用了危險(xiǎn)宏KEY_ALL_ACCESS。dwStartType,dwErrorControl,IpBina}使用了宏SERVICE_WIN32_OWN_PROCESS對訪問類型進(jìn)行了限制。A.2.4日志安全A.2.4.1概述針對日志安全的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系如表A.8所示。表A.8針對日志安全的示例及與標(biāo)準(zhǔn)正文的對照關(guān)系示例語言不要將未經(jīng)驗(yàn)證的用戶輸入記錄日志A.2.4.2不要將未經(jīng)驗(yàn)證的用戶輸入記錄日志當(dāng)日志條目包含未經(jīng)凈化的用戶輸入時(shí)會引發(fā)記錄注入漏洞。惡意用戶會插入偽造的日志數(shù)據(jù),從而讓系統(tǒng)管理員以為是系統(tǒng)行為[OWASP2008]。例如,用戶在將冗長的日志記錄拆分成兩份時(shí),日志中使用的回車和換行符可能會被誤解。記錄注入攻擊可以通過對任何非受信的發(fā)送到日志的輸入進(jìn)行凈化和驗(yàn)證來阻止。對于不要將未經(jīng)驗(yàn)證的用戶輸入記錄日志的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。logger.severe("Userloginlogger.severe("Userloginfailedfor:"+use這個(gè)不符合規(guī)則的代碼示例中,在接收到非法請求的時(shí)候,會記錄用戶的用戶名。這時(shí)沒有執(zhí)行任何輸入凈化。如果沒有凈化,那么可能會出現(xiàn)日志注入攻擊。當(dāng)出現(xiàn)username是david時(shí),標(biāo)準(zhǔn)的日志信息如下所示:SEVERE:Userloginf如果日志信息中使用的username不是david而是多行字符串,如下所示:那么日志中包含了以下可能引起誤導(dǎo)的信息:SEVERE:UserloginfSEVERE:Userloginsucceededfif(!Pattern.matches("[A-Za-z0-9_]+",logger,severe("Userlogger.severe("Userloginfailedfor:"十username);A.3代碼實(shí)現(xiàn)安全A.3.1面向?qū)ο蟪绦虬踩鞟.9針對面向?qū)ο蟪绦虬踩氖纠芭c標(biāo)準(zhǔn)正文的對照關(guān)系比較類而不是類名進(jìn)行安全檢測的方法應(yīng)聲明為private或finalA.3.1.2比較類而不是類名在JVM中,如果兩個(gè)類可以被同一個(gè)類裝載器裝載,并且擁有相同的全名,那么這兩個(gè)類被認(rèn)為是相同的類(并且具有相同的類型)。對于比較類而不是類名的情況,示例1給出了不規(guī)范用法(Java語言)示例。示例2給出了規(guī)范用法(Java語言)示例。if(auth.getClass().getName().equals("com.application.auth.DefaultAuthentica{比較兩個(gè)類是否相同的時(shí)候,需要注意比較兩個(gè)類對象。//Determinewhetherobjectauthif(auth.getClass()==this.getClass().getClassLoader().loadClass("com.application.auth.Defaul}上述示例中,使用class來比較兩個(gè)類是否相同。A.3.1.3確??勺儗ο蟮囊脹]有被泄露用,或者從訪問器返回對象引用。暴露一個(gè)公共靜態(tài)final對象允許客戶修改對象的內(nèi)容(盡管它們不示例1:示例2:publicstaticfinal}A.3.1.4構(gòu)造方法中不要調(diào)用可覆寫的方法在構(gòu)造函數(shù)中調(diào)用可覆寫的方法同時(shí)會在對象創(chuàng)建完成前泄露this引用,這使得其他線程可訪問到未2給出了規(guī)范用法(Java語言)示例。示例1:}}}System.out.printIn("Thisis}}publicstaticvoidmain}}示例2:}publicfinalvoiddoLogic(){System.out.printIn("This}示例1:publicvoidreadSensitiveFiSecurityManagersm=System.getSeif(sm!=null)(//Checkforpermissiontoreadfile}}示例2:publicfinalvoidreadSensitiveFile(){SecurityManagersm=System.getSeif(sm!=null){//Checkforpermission}//Logexception}A.3.1.6不要增加可被覆寫方法和被隱藏方法的可訪問性示例1:System.out.printIn("Supe}System.out.printIn("Subinv}示例2:protectedfinalvoiddoLogic(){System.out.printIn("Supe}A.3.1.7不要定義方法來隱藏基類或基類接口中聲明的方法語言)示例。示例2給出了規(guī)范用法(Java語言)示例。示例1:System.out.printIn("Accountdetailsforadmin:XX"}System.out.println("Accountdetailsfor}GrantAccessuser=newif(username.equals("user.displayAccountStatu}publicstaticvoidmai}代碼中程序員隱藏了static

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論