taibeihacker
Moderator
Java 代码审计背景
1 Java Web 基础
1.1 Servlet
1.1.1 概念
Java Servlet 是運行在Web 服務器或應用服務器上的程序,它是作為來自Web 瀏覽器或其他HTTP 客戶端的請求和HTTP 服務器上的數據庫或應用程序之間的中間層。使用Servlet,您可以收集來自網頁表單的用戶輸入,呈現來自數據庫或者其他源的記錄,還可以動態創建網頁。
Java Servlet 通常情況下與使用CGI (Common Gateway Interface,公共網關接口)實現的程序可以達到異曲同工的效果。但是相比於CGl,Servlet 有以下幾點優勢:
性能明顯更好
Servlet 在web 服務器的地址空間內執行這樣它就沒有必要再創建一個單獨的進程來處理每個客戶端請求
Servlet 是獨立於平台的,因為它們是用Java 編寫的
服務器上的Java 安全管理器執行了一系列限制以保護服務器計算機上的資源。因此,Servlet 是可信的。
Java 類庫的全部功能對Servlet 來說都是可用的。它可以通過sockets 和RMI 機制與applets、數據庫或其他軟件進行交互。
1.1.2 Servlet 架构

1.1.3 Servlet 生命周期
Servlet 生命週期可被定義為從創建直到毀滅的整個過程。以下是Servlet 遵循的過程:
Servlet 初始化後調用init() 方法。
Servlet 調用service() 方法來處理客戶端的請求。 (調用doGet、 doPost等方法)
Servlet 銷毀前調用destroy() 方法
最後,Servlet 是由JVM 的垃圾回收器進行垃圾回收的

1.2 JSP
1.2.1 概念
JSP 全稱Java Server Pages,是一種動態網頁開發技術。它使用JSP 標籤在HTML 網頁中插入Java 代碼。標籤通常以% 開頭,以% 結束。JSP 是一種Java servlet,主要用於實現Java web 應用程序的用戶界面部分。網頁開發者們通過結合HTML 代碼、 XHTML 代碼、XML 元素以及嵌入JSP 操作和命令來編寫JSP
JSP 通過網頁表單獲取用戶輸入數據、訪問數據庫及其他數據源,然後動態地創建網頁。
JSP 標籤有多種功能,比如訪問數據庫、記錄用戶選擇信息、訪問JavaBeans 組件等,還可以在不同的網頁中傳遞控制信息和共享信息。
1.2.2 JSP 处理过程
就像其他普通的網頁一樣,瀏覽器發送一個HTTP 請求給服務器。Web 服務器識別出這是一個對JSP 網頁的請求,並且將該請求傳遞給JSP 引擎。通過使用URL 或者.jsp 文件來完成
JSP 引擎從磁盤中載入JSP 文件,然後將它們轉化為Servlet。這種轉化只是簡單地將所有模板文本改用println() 語句,並且將所有的JSP 元素轉化成Java 代碼
JSP 引擎將Servlet 編譯成可執行類,並且將原始請求傳遞給Servlet 引擎
Web 服務器的某組件將會調用Servlet 引擎,然後載入並執行Servlet 類。在執行過程中,Servlet 產生HTML 格式的輸出並將其內嵌於HTTP response web 中上交給Web 服務器。
Web 服務器以靜態HTML 網頁的形式將web response 返回到瀏覽器中
最終,Web 瀏覽器處理web response 中動態產生的HTML 網頁,就好像在處理靜態網頁一樣。

1.2.3 JSP 的生命周期
编译阶段:Servlet 容器編譯源文件,生成Servlet 類JSP 引擎會檢查是否需要編譯
初始化阶段:加載與JSP 對應Servlet 的類,創建其實例,並調用它的初始化方法
jsplnit()
执行阶段:調用與JSP 對應Servlet 的實例的服務方法
jspService()
销毁阶段:調用與JSP 對應Servlet 的實例的銷毀方法,然後銷毀Servlet 實例
jspDestroy()
1.3 Filter
1.3.1 概念
Servlet 過濾器可以動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。可以將一個或多個Servlet 過濾器附加到一個Servlet 或一組Servlet。 Servlet 過濾器也可以附加到JavaServer Pages(JSP) 文件和HTML 頁面。調用Servlet 前調用所有附加的過濾器。
Servlet 過濾器是可用於編程的Java 類,可以實現以下目的:
在客戶端的請求訪問後端資源之前,攔截這些請求。
在服務器的響應發送回客戶端之前,處理這些響應。
1.3.2 Filter 方法
public void doFilter(ServletRequest, ServletRespor, FilterChain)該方法完成實際的過濾操作,當客戶端請求方法與過濾器設置匹配的URL 時,Servlet 容器將先調用過濾器的doFilter 方法。 FilterChain 用戶訪問後續過濾器。public void init(FilterConfig filterConfig)web 應用程序啟動時,web 服務器將創建Filter 的實例對象,並調用其init 方法,讀取web.xml 配置,完成對象的初始化功能,從而為後續的用戶請求作好攔截的準備工作(filter 對像只會創建一次,init 方法也只會執行一次)。開發人員通過init 方法的參數,可獲得代表當前filter 配置信息的對象。
public void destroy()Servlet 容器在銷毀過濾器實例前調用該方法,在該方法中釋放Servlet 過濾器佔用的資源。
1.4 Listener
監聽器用於監聽web 應用中某些對象、信息的創建、銷毀、增加,修改,刪除等動作的發生,然後作出相應的響應處理。當範圍對象的狀態發生變化的時候,服務器自動調用監聽器對像中的方法。按監聽的對象劃分,可以分為:
ServletContext 對象監聽器
HttpSession 對象監聽器
ServletRequest 對象監聽器
其中前兩種都不適合作為內存Webshell,因為涉及到服務器的啟動跟停止,或者是Session 的建立跟銷毀,目光就聚集到第三種對於請求的監聽上面,其中最適合作為Webshell 的要數ServletRequestListener,因為我們可以拿到每次請求的的事件:ServletRequestEvent,通過其中的getServletRequest() 函數就可以拿到本次請求的request 對象,從而加入我們的惡意邏輯。
2 SSH 框架
2.1 MVC
MVC 模式是軟件工程中的一種軟件架構模式,把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。MVC 模式的目的是實現一種動態的程序設計,使後續對程序的修改和擴展簡化,並且使程序某一部分的重複利用成為可能。除此之外,此模式透過對複雜度的簡化,使程序結構更加直觀。軟件系統透過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。
模型(Model)- 程序員編寫程序應有的功能(實現算法等等)、數據庫專家進行數據管理和數據庫設計(可以實現具體的功能)。
視圖(View)- 界面設計人員進行圖形界面設計。
控制器(Controller)- 負責轉發請求,對請求進行處理性能明顯更好。
2.1.1 MVC 早期架构

2.1.2 MVC 现代架构

2.2 Struts2
Struts2 是一個基於MVC 設計模式的Web 應用框架,它本質上相當於一個Servlet。但是J2EE 的MVC 設計模式中,Struts2 作為控制器(Controller)來建立模型與視圖的數據交互。 Struts 2 是基於Filter,為了實現AOP 的思想。2.2.1 Struts2 架构
Servlet Filters:過濾器鏈,client 的全部請求都要經過Filter 鏈的處理。Struts Core:Struts2 的核心處理部分。
Interceptors: Struts2 的攔截器。 Struts2 提供了非常多默認的攔截器。 也可以自己定義的攔截器,用來實現實際業務要的功能。
User Created:由開發者創建的。包含struts.xml、Action、Template.

2.2.2 Struts2 的 MVC

2.2.3 OGNL 表达式
支持對象方法調用,形式如:objName.methodName();支持類靜態的方法調用和值訪問,表達式的格式為@[類全名(包括包路徑)]@[方法名|值名],例如:@java.lang.String@add('11','hahhaha')
支持賦值操作和表達式串聯,例如:number=18,price=100,calculatePrice(price*number);那麼返回1800;
訪問OGNL 上下文(OGNLcontext)在Struts2 中是ActionContext;
操作(創建)集合對象
2.3 Spring
方便解耦,簡化開發(高內聚低耦合)。 Spring 就是一個大工廠(IoC容器),可以將所有對象創建和依賴關係維護,交給Spring 管理,Spring 工廠是用於生成bean。提供面向切面(AOP)編程。 Spring 可以方便的實現對程序進行權限攔截、運行監控等功能。
方便集成各種優秀框架。 Spring 不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts.Hibernate.MyBatis 等)的直接支持。
降低JavaEE API 的使用難度。 Spring 對JavaEE 開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API 應用難度大大降低。
2.3.1 Spring 核心概念 - IoC
IoC 是Inversion of Control 的縮寫,多數書籍翻譯成「控制反轉」。為了解決對象之間的耦合度過高的問題,軟件專家Michael Mattson提出了IoC 理論,用來實現對象之間的解耦。2004 年,Martin Fowler 探討了同一個問題,既然IOC 是控制反轉,那麼到底是「哪些方面的控制被反轉了呢?」,經過詳細地分析和論證後,他得出了答案:「獲得依賴對象的過程被反轉了」。控制被反轉之後,獲得依賴對象的過程由自身管理變為了由IOC 容器主動注入。於是,他給「控制反轉」取了一個更合適的名字叫做「依賴注入(Dependency Injection)」。
他的這個答案,實際上給出了實現IoC 的方法:注入。所謂依賴注入,就是由IOC 容器在運行期間,動態地將某種依賴關係注入到對象之中。依賴注入(DI)和控制反轉(IOC)是從不同的角度的描述的同一件事情,就是指通過引入IOC 容器,利用依賴關係注入的方式,實現對象之間的解耦。
2.3.2 IoC 优点

2.3.3 Spring 核心概念 - Bean
Spring Bean 是一個被實例化,組裝,並通過Spring IoC 容器所管理的對象。Spring Bean 是任何Spring 應用程序的基本構建塊。大多數應用程序的邏輯代碼都將放在Spring bean 中。
Spring Bean 的管理包括:
創建一個對象
提供依賴項(例如其他bean,配置屬性)。
攔截對象方法調用以提供額外的框架功能。
銷毀一個對象
三種不同的方式定義Spring bean:
使用構造型@Component 註釋(或其衍生物)註釋類
編寫在自定義Java 配置類中使用@Bean 註釋的Bean 工廠方法。
在XML 配置文件中聲明Bean 定義
2.4 Hibernate
2.4.1 定义
Hibernate 是由Gavin King 於2001 年創建的開放源代碼的一種ORM (Object_Relative Mapping,即對象關係映射)框架,是Java 對象和數據庫服務器之間的橋樑,在Java 對象與關係數據庫之間建立某種映射,以實現直接存取Java 對象,將開發人員從公共數據持續性編程工作中解放出來。
2.4.2 ORM
ORM - 對象關係映射,ORM 關注的是對象與數據庫中列的關係3 SSM 框架
3.1 MVC

3.2 Spring MVC
Spring MVC 屬於Spring FrameWork 的後續產品,已經融合在Spring Web Flow 裡面。 Spring 框架提供了構建Web 應用程序的全功能MVC 模塊。使用Spring 可插入的MVC 架構,從而在使用Spring 進行WEB 開發時,可以選擇使用Spring 的Spring MVC 框架或集成其他MVC 開發框架,如Struts1(現在一般不用),Struts2(一般老項目使用)等。Spring MVC 已經成為目前最主流的MVC 框架之一,從Spring3.0 的發布,就已全面超越Struts2,成為最優秀的MVC 框架。它通過一套註解,讓一個簡單的Java 類成為處理請求的控制器,而無須實現任何接口。同時它還支持RESTful 編程風格的請求。
3.3 Spring MVC 执行流程

3.4 Spring MVC 与 Struts 2 的对比
3.4.1 框架机制
Struts2 採用Filter 實現,Spring MVC 則採用Servlet 實現。Filter 在容器啟動之後即初始化;服務停止以後墜毀,晚於Servlet。 Servlet 在是在調用時初始化,先於Filter 調用,服務停止後銷毀。
Spring MVC 基於方法的攔截,有加載一次單例模式bean 注入。而struts2 是類級別的攔截,每次請求對應實例一個新的Action,需要加載所有的屬性值注入,所以,Spring MVC 開發效率和性能高於Struts2。
Struts 2 更加符合AOP 的編程思想,Spring MVC 比較謹慎,在Servlet 上擴展。
3.4.2 拦截机制
Struts2Struts2 框架是類級別的攔截,每次請求就會創建一個Action,和Spring 整合時Struts2 的Action Bean 注入作用域是原型模式prototype,然後通過setter,getter 把request 數據注入到屬性。
Struts2中,一個Action 對應一個request,response 上下文,在接收參數時,可以通過屬性接收,這說明屬性參數是讓多個方法共享的。
Struts2 中Action 的一個方法可以對應一個url,而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法了。
SpringMVC
Spring MVC 是方法級別的攔截,一個方法對應一個Request 上下文,所以方法直接基本上是獨立的,獨享request,response 數據。而每個方法同時又何一個url 對應,參數的傳遞是直接注入到方法中的,是方法所獨有的。處理結果通過ModeMap 返回給框架。
在Spring 整合時,Spring MVC 的Controller Bean 默認單例模式Singleton,所以默認對所有的請求,只會創建一個Controller,有因為沒有共享的屬性,所以是線程安全的,如果要改變默認的作用域,需要添加@Scope 註解修改。
3.5 Mybatis
MyBatis 是一個支持普通SQL 查詢、存儲過程以及高級映射的持久層框架,它消除了幾乎所有的JDBC 代碼和參數的手動設置以及對結果集的檢索,並使用簡單的XML 或註解進行配置和原始映射,用以將接口和Java 的POJO (Plain Old Java Object,普通Java對象)映射成數據庫中的記錄,使得Java 開發人員可以使用面向對象的編程思想來操作數據庫。4 Spring Boot Spring Cloud
4.1 Spring Boot
4.1.1 Spring Boot 定义
Spring Boot 是Spring 開源組織下的一個子項目,也是Spring 組件一站式解決方案,主要是為了簡化使用Spring 框架的難度,簡省繁重的配置。Spring Boot 提供了各種組件的啟動器(starters),開發者只要能配置好對應組件參數,SpringBoot 就會自動配置,讓開發者能快速搭建依賴於Spring 組件的Java 項目。
Spring Boot 不但能創建傳統的war 包應用,還能創建獨立的不依賴於任何外部容器(如:tomcat)的獨立應用,使用java -jar 命令就能啟動。同時,Spring Boot 地提供了一個命令行工具來執行Spring 的腳本。
4.1.2 Spring Boot 特点
獨立運行:打包容器,生成jar簡化Maven 配置:spring-boot-starter-xx
自動配置:根據當前類路徑下的類或者jar 包裡面來的類來自動配置Spring Bean 。
無代碼生成和XML 配置:借助註解
應用監控:提供一系列端點可以監控服務及應用,能對Spring 應用做健康檢測。
4.2 Spring Cloud
4.2.1 Spring Cloud 定义
Spring Cloud 是一系列框架的有序集合。它利用Spring Boot 的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,都可以用SpringBoot 的開發風格做到一鍵啟動和部署。Spring Cloud 並沒有重複製造輪子,它只是將目前各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過Spring Boot 風格進行再封裝屏蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分佈式系統開發工具包。
4.2.2 Spring Cloud Alibaba 框架
