學術論文分享-Java企業應用程式靜態分析

2021-02-20 北郵系統安全中心

今天分享一篇2020年在PLDI上發表的一篇關於Java企業應用靜態分析的論文——「Static Analysis of Java Enterprise Applications: Frameworks and Caches, the Elephants in the Room」

論文題目中」 the Elephants in the Room」翻譯為「房間裡的大象」,這是英語中的一個隱喻,形容一個明明存在的問題,卻被人刻意的迴避及無視的情形。這也體現了本篇論文關注的是那些被現有靜態分析框架所忽視的,但是在企業應用程式中大量存在的「Frameworks and Caches」(框架和緩存)的靜態分析方法。

1.什麼是靜態分析

在介紹論文之前,我先來介紹一下什麼是靜態分析:靜態分析就是在不運行程序的情況下對源碼進行詞法分析、語法分析、控制流、數據流、指針分析等,來檢測程序是否滿足規範性和安全性等。

靜態分析不同於動態分析,動態分析通常是通過執行程序,根據程序運行返回結果和程序狀態去分析。

靜態分析中有兩個常見的名詞:

soundness:對程序進行了over-approximate過擬合,不會漏報(有false positives誤報)。

completeness:對程序進行了under-approximate欠擬合,不會誤報(有false negatives漏報)。

從圖1中可以清晰的理解這兩個名詞,其中綠色區域表示所有的Truth,也是理想狀態下靜態分析應該找出的所有情況,如果對程序進行了過擬合分析也就是圖中紅色區域(Soundness),它雖然包含了所有Truth不會產生漏報,但是會有誤報存在;同理Completeness沒有包含所有的Truth,但是它不會產生誤報,存在一定的漏報。

圖1 Soundness & Completeness

靜態分析存在的一大問題

靜態分析面臨的一個很大的問題就是很難處理程式語言帶有的動態特性。例如Java中的反射。反射技術就存在很強的動態性,只有在程序運行時才能知道內存中的哪個字節碼文件被反射使用;現有的靜態分析框架對Java中的反射就沒有較好的解決方法。

2.本文所求解的問題

本文主要求解兩個問題:

1.企業應用程式在開發中大量使用框架,框架為了儘可能通用,採取了許多動態技術,例如依賴注入,對於應用程式中的邏輯,框架通常採用註解或xml等配置文檔來實現;這加大了靜態分析的難度,該如何對企業應用程式中使用的框架進行靜態分析。

2.在企業應用程式中會經常用到緩存這一技術,從緩存中讀取數據的操作是很難靜態分析的。例如Spring的視圖對象做緩存,有利於前端解析處理。該如何分析通用、異構的數據結構的緩存。

企業應用程式靜態分析面臨的可擴展性和精確性挑戰:

1.靜態分析的完整性會影響分析的質量,由於框架的高度抽象和可配置性,嚴重影響了靜態分析的完整性。

2.靜態分析的可擴展性和精確性的權衡,如果可擴展性很好那必然會喪失精確性,如果精確性很好,那就相當於是某個具體應用程式的定製產品,可擴展性必然下降。

3.本文貢獻與創新

本文提出了JackEE,一個企業應用程式靜態分析框架,表明對現實企業應用程式進行可擴展、高完整性、高精度的靜態分析是可能的。

本文介紹了用於識別和建模企業應用程式入口點的技術和一般概念。JackEE定義了一個詞彙表,來表達企業框架的行為。

構建sound-modulo-analysis,一種對Java數據結構分析的模型,不像其他模型一個直接丟棄信息,而是通過替換保留了數據結構的全部動態行為但是簡化了靜態分析。

4.企業中常用開發框架的考察

為著眼於如何靜態的對程序進行建模,論文中主要對這些框架進行三個方面的考察。

1.What:應用功能單元之間交互的 關鍵概念,實體和 數據/對象的種類。

2.Where:應用功能的入口點或者內部的連接點。

3.How:用來描述「What」或「Where」的方式,例如:子類型,XML屬性,Java註解等。

Servlet:

Servlet是常用的Web應用程式開發的技術。有Generic Servlets和Http Servlets.等

What:不同類型的servlet,servlet中的request/response對象,filters

Where:生命周期方法如init,destroy等,service,doFilter, doGet, doPost。

How:繼承實現抽象類。

Enterprise Java Beans(EJB):

可以簡化應用開發的一項技術。

What:不同類型的beans,bean客戶端類。

Where:生命周期方法和bean的方法。

How:Java註解或XML配置。

Spring體系:

Spring是Java開發中使用較多的框架。

What:controllers,interceptors,authentication managers,providers,and beans

Where:controller的方法和其他handler類 例如:preHandle,postHandle,authenticate等。

How:Java註解,XML配置,子類繼承。

5.框架建模方法和舉例

在介紹論文中建模方法之前,我先對Datalog語言進行一個簡單的介紹,只有了解了Datalog的一些基本語法,才能理解之後論文中的建模方法。

Datalog簡介:

Datalog語言是一種聲明式程式語言,在靜態分析領域使用非常廣泛,我們常見的SQL語言就是一種聲明式語言。聲明式語言更偏向於去描述「需要做什麼(What to do)」,而不是「怎麼做(How to do)」,它更像是一份規範,更適合人來理解。

Datalog這門語言關心的對象有兩部分,data + logic,其中data是一些列的謂詞(predicate),而logic則是很多規則(rule)。謂詞是陳述(statement)的集合,也可以理解成SQL中的表或者關係(relation);原子(atoms)是Datalog語言中的基本元素,包括關係原子和算術原子,其中關係原子形式記作P(x1, x2, x3),其中P為謂詞名,xn為參數;算術原子attr >= var,其中attr為謂詞中的一個列,var為一個變量或者常量。

規則是邏輯的表達,形式為H <- B1, B2,...,Bn,H為規則的頭部,是規則的結論(consequent),B為規則體,也是規則的前因(antecedent),Bi也被叫作子目標(subgoal),若且唯若前因為真時,結論為真。「,」在規則中充當「and」的作用,「;」在規則中充當「or」的作用,而「!」充當取反的作用。

建模:

首先構造詞彙表,這個詞彙表就是一些關係原子,詞彙表如下:

圖2 基礎關係,框架在此基礎上建模

圖2展示了框架建模詞彙表的一個關鍵概念的例子,既與程序文本和配置相關(例如,Class_Annotation, XMLNode),也與程序語義相關(例如,Interceptor, Servlet),或者與分析語義相關(例如,GeneratedObject, EntryPointClass)。如果碰到一個EntryPointClass或者Controller等,都會觸發進一步的推理。

圖3 程序相關信息,用於框架規範(和進一步分析)。

模擬對象創建規則:

一旦入口點被識別,就需要創建入口點使用的模擬對象。

創建模擬對象的規則如下:

1.給定一個入口點方法m和它的聲明類型C,則為入口點方法m創建一個C類型的接收器模擬對象,靜態分析認為this指向這個模擬對象。

2.給定一個入口點方法m及其帶有索引i和類型T的參數

a)如果應用程式中有T類型的具體子類型,就為程序中每個子類型創建模擬對象。

b)如果應用程式中沒有T的子類型,就找入口點方法中T類型的所有強制類型轉換S,為每個S創建一個模擬對象。

c)遵循每種類型一個模擬對象的原則,確保無論入口點數量如何,分析都保證可伸縮性。

d)靜態分析認為參數i指向上述模擬對象。

建模舉例:

利用圖2的基礎關係和圖3的程序相關信息來對一些程序框架進行建模。

Servlet

首先對Servlet進行建模分析,在Java Servlet API中,所有的Servlet都是javax.servlet.GenericServlet的一個子類型, GenericServlet類位於Servlet類層次結構的頂部,因此可以進行如下建模。

圖4 Servlet建模

另外也認為接收ServletRequest或ServletResponse任意一個對象的也是入口點。

圖5 Servlet入口方法

過濾器是對資源請求和資源響應進行過濾的類,通過實現Filter接口,重寫doFilter方法,過濾器類也是一個通用的入口點。

圖6 Servlet入口類

Spring

將帶有@Controller註解的類作為入口類,帶有@RequestMapping的標記為入口點方法。

圖7 SpringMVC入口類

SpringMvc中攔截器是通過實現HandleInterceptor接口或繼承HandleInterceptorAdapter類實現的。

圖8 攔截器入口類

Spring Security中自定義的身份認證服務通過XML文檔進行配置。

圖9 權限XML配置

圖10 攔截器建模

Bean

在框架中bean是最常出現的,企業應用程式依賴beans實現可重用代碼。因此靜態分析要想保證完整性,對於bean的分析是不可忽視的。完整的bean對象以及它們的可傳遞依賴關係是很重要的,這樣分析可以完全分析bean代碼。

對註解標記的bean進行識別:

圖11 Bean註解建模

對XML文檔配置的bean進行識別:

圖12 BeanXML建模

6.緩存的處理

2-object-sensitive analysis 這種分析方法在對java.util包中的這些數據結構類的分析有很好的效果,但是通過分析前人的工作發現,用這個方法對一個小應用程式進行分析,其中對java.util的分析佔了整個靜態分析耗時的三分之二。

產生這種現象的原因是應用程式中有大量高度通用且異構的數據緩存,由於應用程式的分布式特性和水平擴展需求,資料庫相關對象,身份信息映射,視圖對象,業務邏輯相關對象都常常會被緩存。

在Spring中使用@EnableCaching and @Cacheable註解來實現任意bean的緩存。

提出一個sound-modulo-analysis的分析模式,通過替換修改一些原來的代碼,在不破壞原有一些行為特徵的情況下,簡化靜態分析。

通過分析發現,程序分支的條件,分析語句的順序,和數組內容的精確索引都不會影響靜態分析,根據這個特性,實現了數據結構的一個簡化版本。

sound-modulo-analysis儘可能的保證Java庫的原始行為。

對HashMap進行簡化,代碼如下(左側為原始代碼右側是簡化後代碼)

圖13 HashMap重構

7.JackEE評估

左側是評估程序時所分析的所有企業應用,和Doop進行完整性對比,可以看到JackEE在所有分析的企業應用程式中方法的可達率都超過了Doop框架,JackEE的分析平均應用內可達性為58.04%,在alfresco也降至不低於43.48%。相比之下,Doop的平均覆蓋率為14.48%,其中在alfresco和pybbs的覆蓋率分別降至約1.8%和0.0%,alfresco和pybbs都通過框架特定的機制定義了入口點和進一步的功能的。但是Doop卻檢測不到,alfresco既有XML配置的入口點,也有一個自定義的基於Spring的RESTful風格的API。pybbs的入口點是用Spring注釋給出的。然後,兩個應用程式都使用注釋進行依賴注入。可見其分析的完整性。

圖14 JackEE評估

從這張圖可以看出JackEE採用的mod-2objH方法比傳統方法分析效率上有明顯提升,有的程序執行分析時所消耗的時間幾乎和上下文無關(ci)分析所用時間相近,可見JackEE有較高的分析效率。

本文提出的對Java企業應用程式中框架和緩存的靜態分析方法相比現有靜態分析方法有較好的準確性和可擴展性。

論文下載連結:https://pdfs.semanticscholar.org/0f24/74c24741b34ddffdd512ce2d556dd57afe9a.pdf

Youtube講解地址:https://www.youtube.com/watch?v=kADROzL8fJU

參考:https://www.jianshu.com/p/8d06766d232c,https://zhuanlan.zhihu.com/p/161700173

相關焦點

  • Java程式設計師的良藥:應用程式的開發技巧
    【IT168 技術】 假如你是一名Java開發者,正在開發和維護包含2000個類並使用了很多框架的應用程式。你要如何理解這些代碼呢?在典型的Java企業項目小組中,大部分能夠幫你的高級工程師看起來都很忙,文檔也很少。你需要儘快交付成果,並向項目組證明自己的能力。你會如何處理這種狀況呢?
  • JAVA入門:從什麼是JAVA到編寫第一個java程序只需看這一篇
    Java語言作為靜態面向對象程式語言的代表,極好地實現了面向對象理論,允許程式設計師以優雅的思維方式進行複雜的編程。Java具有簡單性、面向對象、分布式、健壯性、安全性、平臺獨立與可移植性、多線程、動態性等特點 。Java可以編寫桌面應用程式、Web應用程式、分布式系統和嵌入式系統應用程式等。
  • 給Java新手的一些建議——Java知識點歸納(Java基礎部分)
    寫這篇文章的目的是想總結一下自己這麼多年來使用java的一些心得體會,主要是和一些java基礎知識點相關的,所以也希望能分享給剛剛入門的Java程式設計師和打算入Java開發這個行當的準新手們,希望可以給大家一些經驗,能讓大家更好學習和使用Java。這次介紹的主要內容是和J2SE相關的部分,另外,會在以後再介紹些J2EE相關的、和Java中各個框架相關的內容。
  • 大型企業JVM性能調優實戰Java垃圾收集器及gcroot
    本次的系列課程需要今天再次分享這次的課程,今晚分享之後就完結了,歡迎大家來一起閱讀!
  • 啟動一個沒有 main 函數的 java 程序
    java 使用者最熟悉的方法, 每個 Java 應用程式都必須有且僅有一個 main 方法 這種說法。2、接下來就是到我們前面反推到的 LoadMainClass 了,找到我們真正 java 程序的入口類,就是我們應用程式帶有 main 函數的類。3、獲取應用程式 Class -> GetApplicationClass,這裡簡單說下,因為和最後的那個 demo 有關,也和本文的題目有關。
  • 學術論文投稿與返修(Rebuttal)分享
    來自 | 知乎作者 | 葉茫地址 | https://zhuanlan.zhihu.com/p/344008879編輯 | 機器學習算法與自然語言處理公眾號本文僅作學術分享以筆者近期的幾篇論文投稿為例,分享論文學術論文投稿與返修(Rebuttal)的經驗。講座目的:希望能夠給大家論文投稿和Rebuttal帶來一些幫助。主要目的: 1)了解期刊、會議投稿和審稿流程 ;2)了解論文Rebuttal常見問題和常用表達;3)了解論文投稿的一些建議和經驗。
  • 深入分析Java中的關鍵字static
    這篇文章就把java中static關鍵字的使用方法的原理進行一個深入的分析。先給出這篇文章的大致脈絡:首先,描述了static關鍵字去修飾java類、方法、變量、代碼塊的方法然後,從底層分析static關鍵字,接下來,給出static的一些使用場景和案例最後,對static進行一個總結,包括和普通變量的區分。
  • 靜態脫敏產品三個典型應用場景分析
    靜態脫敏典型應用場景分析——開發測試、數據共享、科學研究上回說到,美創科技新手銷售小李歷經千辛終於首戰告捷,完成數據脫敏第一單→前情查閱【美創資訊】:銷售新手的數據脫敏「成單記」▼>靜態脫敏產品三個典型應用場景分析在數據流動、共享、交換成為趨勢的今天,數據脫敏已經成為實現敏感數據保護的重要手段之一。
  • 面試官:為什麼java中靜態方法不能調用非靜態方法或變量?
    這個可能很多人之前學習jvm的時候都會遇到,屬於一個小問題,寫這篇文章的原因是我在看java相關的面試題目中遇到的,因此順手總結一下:一、例子我們先看效果:我們在靜態方法我們反過來看看:反過來沒有一點問題,接下來我們解釋一下原因:二、原因解釋我們需要首先知道的是靜態方法和靜態變量是屬於某一個類,而不屬於類的對象。我們不直接講原因,先從jvm說起:這是一張類加載的生命周期圖。
  • Java面向對象程序設計的基本概念
    面向對象程序設計是將人們認識世界過程中普遍採用的思維方法應用到程序設計中。對象是現實世界中存在的事物,它們是有形的,如某個人、某種物品;也可以是無形的,如某項計劃、某次商業交易。對象是構成現實世界的一個獨立單位,人們對世界的認識,是從分析對象的特徵入手的。對象的特徵分為靜態特徵和動態特徵兩種。靜態的特徵指對象的外觀、性質、屬 性等;動態的特徵指對象具有的功能、行為等。
  • Java的21個技術點和知識點歸納
    寫這篇文章的目的是想總結一下自己這麼多年來使用java的一些心得體會,主要是和一些java基礎知識點相關的,所以也希望能分享給剛剛入門的
  • 有史以來25個最偉大的Java應用程式
    經過詹姆斯·高斯林(James Gosling)領導的java開發過程幾年中,核心意義是「編寫一次,隨處運行」 Java平臺,將其範圍從最初的交互式電視設計重新定位為新興的World Wide Web應用程式。讓我們介紹一下25個最偉大的Java應用程式:1.
  • 別翻了,這篇文章絕對讓你深刻理解java類的加載以及ClassLoader源碼分析
    元數據驗證:對字節碼描述的信息進行語義分析(注意:對比javac編譯階段的語義分析),以保證其描述的信息符合Java語言規範的要求;例如:這個類是否有父類,除了 java.lang.Object之外。字節碼驗證:通過數據流和控制流分析,確定程序語義是合法的、符合邏輯的。符號引用驗證:確保解析動作能正確執行。
  • 學術論文摘要漢譯英文體特點分析
    摘要是學術論文的主要組成部分,是以提供論文內容梗概為目的,不加評論和補充解釋,簡明確切地記述文獻重要內容的短文,對於論文發表以及學術交流有著非常重要的意義。隨著國際學術交流日益增多,學術論文大部分要求附有英文摘要。為使學術論文的中、英文摘要達到真正的等效,藍譯編譯認為,在翻譯過程中應當注重其文體特點。文體特點是指語篇中所表現出來的文章體裁特徵的綜合,以下我們就來分析摘要的文體特點。
  • 於企業應用程式而言,Go比Java更明智!
    1.Go-to-Market Time  曾幾何時,Java被譽為最簡單最容易編譯的語言,但Go語言以乾淨的語法和緊湊的形式很快得到了用戶的青睞,使得企業應用程式以閃電般的速度發展,幫助企業縮短上市時間。因為Go語言可以在最快的時間為企業提供出色的、安全的、無差錯的企業應用程式,這讓以龐大的庫和框架著稱的Java也變得黯然失色。
  • 「三段論」結構學術論文的寫作要點,附分析樣本
    「總分總」結構學術論文的寫作要點,附分析樣本如前所述,我們從最大公約數的角度入手,把學術論文正文的組織結構分為三種,分別是總——分——總結構、三段論結構和並列式結構。這篇文章呢,我們一起了解一下「三段論」結構學術論文的寫作要點。
  • 你必須掌握的 21 個 Java 核心技術!
    Java的運行這條可能出看很簡單,java程序的運行誰不會呢?不過很多時候, 我們只是單純通過IDE去執行java程序,底層IDE又是如何執行java程序呢?很多人並不了解。這個知識點是最最基本的java開發者需要掌握的,第一個肯定是教你如何在命令行中執行java程序,但是很多人一旦把java學完了,IDE用上了,就把這個都忘了。
  • 全方位解析Java序列化
    static 靜態變量和 transient 修飾的欄位是不會被序列化的static 靜態變量和 transient 修飾的欄位是不會被序列化的。我們來看例子分析一波~Student 類加了一個類變量 gender 和一個 transient 修飾的欄位 specialty。
  • Java 基礎知識總結(一)之Java 概述
    各位好,由於前幾天在考量是否在百家號與大家分享成長。斷續了文章的更新,今天開始為大家講解Java基礎。希望大家多多支持!寫代碼1,明確需求。我要做什麼?2,分析思路。我要怎麼做?1,2,3。Java Platform Enterprise Edition,開發企業環境下的應用程式,主要針對web 程序開發;JAVASE:Java Platform Standard Edition,完成桌面應用程式的開發,是其它兩者的基礎;JAVAME:Java Platform Micro Edition,開發電子消費產品和嵌入式設備
  • Java初學者入門指南,值得收藏~
    很多Java編程初學者在剛接觸Java語言程序的時候,不知道該學習掌握哪些必要的基礎知識。小編總結了零基礎學習Java程式語言的幾個基礎知識要點。希望能夠對剛入門的Java新手有幫助。初學者先弄清這些Java的基本概念也是必不可少的,死記硬背肯定是不行的,重在理解,理解它們之間的區別與聯繫,分別有哪些應用。想想這些代碼中用到了哪些知識點。