JAVA代码审计(三)-基础知识
一、Java 三层架构
Java 项目开发过程中把整个项目分为三层:表现层、数据访问层、业务逻辑层。
- 表现层:MVC(Model-ViewControler)模式,采用
JSP/Servlet
技术进行页面效果显示,即用户操作界面,为用户提供交互操作。 - 数据访问层: 采用
DAO
模式,DAO
为提供访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口,也就是哪个类对应哪个表,哪个属性对应哪个列,为业务逻辑层提供数据,根据传入的值来操作数据库,增、删、改、查。 - 业务逻辑层:采用事务脚本模式,负责关键业务的处理和数据传递,复杂的逻辑判断和涉及到数据库的数据验证均需要在此进行处理,根据用户传入的值返回相关数据或处理相关逻辑。
SSH 框架
1 | 业务层——Spring |
SSM框架
1 | 业务层——Spring |
二、MVC模式
MVC,全称是 Model-View-Controller(模型-视图-控制器)
,是一种设计的规范,一种架构的模式。
1 | Model 模型:提供数据和行为,即 Dao 和 Service |
工作流程
1 | Controller层接收到用户的请求,并决定应该用哪个Model来进行处理,然后由 Model 使用逻辑处理用户的请求并返回数据;最后,返回的数据通过View层呈现给用户。 |
三、Maven
Maven
是一个项目管理工具,它包含了一个对象模型(Project Object Model),是一组标准集合,一个依赖管理系统,用来运行定义在生命周期阶段中插件目标和逻辑。核心功能为:通过 pom.xml
文件的配置获取 jar 包不用手动去添加 jar 包。日常项目开发需要应用各种jar包,少则几十、多至上百,若每一个jar都使用人工导入则大大增加工作量。Maven
使这一部分工作变得简单,开发者只需通过定义 pom.xml
,maven
即可调用仓库的 jar 包直接导入。
四、pom.xml
POM 是项目对象模型 (Project Object Model) 的简称,它是 Maven 项目中的文件,使用XML表示,名称叫做pom.xml。该文件用于管理源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等。Maven 项目中必须包含 pom.xml 文件。例子如下:
1 |
|
五、Spring Boot
SpringBoot
是一款基于 JAVA
的开源框架。目的是为了简化 Spring
应用搭建和开发流程。现在绝大多数的新项目都基于 Spring Boot
的 Spring MVC
来实现。
1、Spring MVC
Spring MVC
是 Spring
提供的一个基于 MVC
设计模式的轻量级 Web
开发框架,本质上相当于 Servlet
(Servlet 是运行在 Web
服务器或应用服务器上的程序,它是作为来自 Web
浏览器或其他 HTTP
客户端的请求和 HTTP
服务器上的数据库或应用程序之间的中间层。)
2、接口
DispatcherServlet 接口
:前端控制器,所有请求都经过它来统一分发,DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的 Controller。HandlerMapping 接口
:完成客户请求到 Controller 的映射。Controller接口
:并发用户处理 DispatcherServlet、HandlerMapping 请求,因此实现Controller接口时,必须保证线程安全并且可重用。
3、DispatcherServlet
是整个Spring MVC的核心。主要负责截获请求并将其分派给相应的处理器处理。其主要工作有以下三项:
- 截获符合特定格式的URL请求
- 初始化 DispatcherServlet 上下文对应 WebApplicationContext ,并将其与业务层、持久化层的 WebApplicationContext 建立关联。
- 初始化 Spring MVC 的各个组成组件,并装配到 DispatcherServlet 中。
六、Java 反射机制
Java 反射机制可以无视类方法、变量去访问权限修饰符(如 protected、private等),并且可以调用任何类的任意方法、访问并修改成员变量值。即当我们在能控制反射的类名、方法名、参数的前提下,发现了一处 Java 反射调用的漏洞,我们就可以任意构造攻击。
1、什么是反射
反射使 Java 代码能够发现有关已加载类的字段、方法和构造函数的信息,并在安全限制内使用反射的字段、方法和构造函数对底层对应的对象进行操作。即通过反射我们可以在运行时获得程序或程序集中每一个类型的成员和成员信息。在运行状态中通过反射机制,我们能判断一个对象所属的类,了解任意一个类的所有属性和方法,能够调用任意一个对象的任意方法和属性。
2、不安全的反射机制
Java 的反射机制可以无视类方法、变量访问权限修饰符,可以调用任何类的任意方法、访问并修改成员变量值,那么这可能导致安全问题,如果一个攻击者能够通过应用程序创建意外的控制流路径,那么就有可能绕过安全检查发起相关攻击。假设有段代码如下:
1 | String name = request.getParameter("name"); |
存在一个字段为 name,当获取用户请求的 name 字段后进行判断,如果请求的是 Delect 操作,则执行DelectCommand 函数,若执行的是 Add 操作,则执行 AddCommand 函数,如果不是这两种操作,则执行其他代码。
此时,假如有位开发者看到了这段代码,他觉得可以使用Java 的反射来重构此代码以减少代码行,如下所示:
1 | String name = request.getParameter("name"); |
这样的重构看起来使得代码行减少,消除了 if/else 块,而且可以在不修改命令分派器的情况下添加新的命令类型,但是如果没有对传入进来的 name 字段进行限制,那么我们就能实例化实现 Command 接口的任何对象,从而导致安全问题。实际上,攻击者甚至不局限于本例中的 Command 接口对象,而是使用任何其他对象来实现,如调用系统中任何对象的默认构造函数,再如调用 Runtime 对象去执行系统命令,这就可能导致远程命令执行漏洞,因此不安全的反射的危害性极大,也是我们审计过程中重点关注的内容。
七、Java EE 核心技术
- JDBC:Java 数据库链接,提供了客户端访问数据库应用的程序接口以及查询和更新数据库中数据的方法。
- JNDI:Java 命名和目录接口,是 JAVA 的一个目录服务应用程序界面,提供了一个目录系统,并将服务名称与对象关联起来,使开发者在开发过程中可以用名称来访问对象。
- RMI:远程调用方法,为 Java 的一组拥护开发分布式应用程序的 API,增强了Java 开发分布式应用的能力。
- Servlet:Java Web 容器中运行的程序,通常用来处理较为复杂的服务端业务逻辑。使用 Java 编写而成的服务器程序,狭义的 Servlet 为 Java 语言实现的一个接口,广义的说就是任何实现该 Servlet 接口的类,主要功能在于交互式地浏览和修改数据,生成动态的 web 内容。
八、Java 基础语法
1、前言
Java 是一个解释型的语言,可跨平台执行。一个 Java 程序可以认为是一系列对象的集合,这些对象通过调用彼此的方法来协同工作,每个 Java 文件都是一个类,同一文件夹下可以互相调用其他文件下的类,不同文件夹下可以通过 import 命令进行导入。其中 Java 中的包其实就是文件夹,在同一个包中可以理解成同一文件夹下。
2、语法注意点
注意点 | 简述 |
---|---|
大小写敏感 | Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的 |
类名 | 对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass |
方法名 | 所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写 |
源文件名 | 源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误) |
主方法入口 | 所有的 Java 程序由 public static void main(String[] args) 方法开始执行 |
3、简单实例
1 | public class HelloWorld { |
4、构造函数
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
- 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
一个类可以有多个构造函数,根据对象的创建情况触发不同的构造函数,若在创建对象的时候传入了参数,则会触发第二个构造函数,如果不传入参数则会触发第一个构造函数,例子如下:
1 | class test{ |
运行结果如下:
5、类与对象
假设有一个类名为Test,创建对象abc,语法如下
1 | // 类名称 对象名 = new 类名称(); |
类:类是一个模板,它描述一类对象的行为和状态。例子如下:
1 | public class Dog { |
对象:对象是类的一个实例。例子如下:
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。
1 | public class Puppy{ |
6、变量与常量
例子如下,a为变量,b在char前加了 final 为常量,常量无法被更改。
1 | char a = 'a'; |
7、访问实例变量和方法
通过已创建的对象来访问成员变量和成员方法,如下所示:
1 | 实例化对象:Object referenceVariable = new Constructor(); |
实例,下面的例子展示如何访问实例变量和调用成员方法:
1 | public class Puppy{ |
运行结果如下:
8、接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口的声明语法格式如下:
1 | [可见度] interface 接口名称 [extends 其他的接口名] { |
Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。
1 | /* 文件名 : NameOfInterface.java */ |
实例,Animal.java 文件代码:
1 | /* 文件名 : Animal.java */ |
接口的实现,当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。实例
1 | /* 文件名 : MammalInt.java */ |
以上实例编译运行结果如下:
1 | Mammal eats |
九、参考文章
https://blog.csdn.net/chehec2010/article/details/123997607
https://blog.csdn.net/jianyuerensheng/article/details/51258942
https://www.freebuf.com/vuls/344685.html
https://www.cnpanda.net/codeaudit/705.html
https://blog.csdn.net/qq_41874930/article/details/115614958