JAVA代码审计

MVC模型

MVC模式是一种软件框架模式,被广泛应用在JavaEE项目的开发中。
MVC即模型(Model)、视图(View)、控制器(Controller)。

模型(Model)

模型是用于处理数据逻辑的部分。
所谓数据逻辑,也就是数据的映射以及对数据的增删改查,Bean、DAO(dataaccess object,数据访问对象)等都属于模型部分。

视图(View)

视图负责数据与其它信息的显示,也就是给用户看到的页面。
HTML、JSP等页面都可以作为视图。

控制器(controller)

控制器是模型与视图之间的桥梁,控制着数据与用户的交互。
控制器通常负责从视图读取数据,处理用户输入,并向模型发送数据,也可以从模型中读取数据,再发送给视图,由视图显示。

整体结构

首先要了解项目整体结构。大致了解作者编写逻辑,搞清请求流程。
src/main下面有两个目录,分别是java和resources,java目录中主要存放的是java代码,resources目录中主要存放的是资源文件,比如:html、js、css等。

java目录

annotation:放置项目自定义注解;

controller/:存放控制器,接收从前端传来的参数,对访问控制进行转发、各类基本参数校验或者不复用的业务简单处理等;

dao/:数据访问层,与数据库进行交互,负责数据库操作,在Mybaits框架中存放自定义的Mapper接口;

entity/:存放实体类;

interceptor/:拦截器;

service/:存放服务类,负责业务模块逻辑处理。Service层中有两种类,一是Service,用来声明接口;二是ServiceImpl,作为实现类实现接口中的方法;

utils/:存放工具类;

dto/:存放数据传输对象(DataTransfer Object),如请求参数和返回结果;

vo/:视图对象(ViewObject)用于封装客户端请求的数据,防止部分数据泄漏,保证数据安全

constant/:存放常量;

filter/:存放过滤器。

resources目录

mapper/:存放Mybaits的mapper.xml文件;

static/:存放静态资源文件目录(Javascript、CSS、图片等),在这个目录中的所有文件可以被直接访问;

templates/:存放模版文件;

application.properties或application.yml:Spring Boot默认配置文件。

URL请求流程

用户请求URL发送到服务器,服务器解析请求后发送到后端代码处理请求。

在后端代码处,首先经过Filter(过滤器)和Interceptor(拦截器),然后根据请求的URL映射到绑定的Controller,之后调用Service接口类,然后再调用serviceImpl接口实现类,最后调用DAO。

controller:负责简单的逻辑处理和参数校验功能,之后调用Service;

service:接口类,主要负责业务模块逻辑处理;

serviceImpl:接口实现类,实现类实现service接口中的方法;

DAO:如果service涉及数据库操作就会调用DAO。DAO主要处理数据库操作。DAO只做中间传递角色

常见注解和函数

注解

@Controller 注解:标注该类为controller类,可以处理http请求。

@Controller一般要配合模版来使用。现在项目大多是前后端分离,后端处理请求,然后返回JSON格式数
据即可,这样也就不需要模板了。

@ResponseBody 注解:将该注解写在类的外面,表示这个类所有方法的返回的数据直接给浏览器。

@RestController 相当于 @ResponseBody 加上 @Controller

@RequestMapping 注解:配置URL映射 ,可以作用于某个Controller类上,也可以作用于某Controller类下的具体方法中,说白了就是URL中请求路径会直接映射到具体方法中执行代码逻辑。

@RequestParam 注解:将请求参数绑定到你控制器的方法参数上(是springmvc中接
收普通参数的注解),常用于POST请求处理表单。

@PathVariable 注解:接受请求URL路径中占位符的值
如下代码

@Controller
@ResponseBody
@RequestMapping("/hello")
public class HelloController {
   
	@RequestMapping("/whoami/{name}/{sex}")
	public String  hello(@PathVariable("name") String name,@PathVariable("sex") String sex){
   
		return "Hello" + name + sex;
	}
}

函数

1、不可信数据入口方法

方法 说明
getParameter request类获取参数方法
getParameterNames 获取参数名
getParameterValues 获取参数值
getParameterMap 获取参数map类型
getQueryString 获取URL的value值
getHeader 获取http请求头
getHeaderNames 获取请求头名
getRequestURI 获取请求URL
getCookies 获取cookie
getRequestedSessionId 获取sessionid
getInputStream 获取输入数据
getReader 获取请求内容
getMethod 获取请求方法
getProtocol 获取请求协议
getServerName 获取服务名
getRemoteUser 获取当前缓存的用户
getUserPrincipal 获取用户指纹

2、不可信文件访问方法

方法 说明
java.io.FileInputStream 文件输入
java.io.FileOutputStream 文件输出
java.io.FileReader 文件读取
java.io.FileWriter 文件写入

审计思路

一、第三方组件漏洞审计

maven看pom.xml,整理出来第三方组件以及版本号,并说明存在漏洞组件

框架相关:S2、shiro、Spring
中间件相关:JBoss、Weblogic、Jenkins
Java库相关:Fastjson、Jackson
第三方编辑器:UEditor、KindEditor、FCKeditor

用脚本PomEye-main

python3 main.py

在这里插入图片描述

二、看配置文件

1、看过滤器 filter

这里需要清楚一个概念,过滤器在任何框架都可以使用,而拦截器是Spring MVC独有的。
而过滤器需要配置在web.xml 里面,而拦截器会配置在springmvc.xml文件里面

搜索代码:doFilter

如xss过滤器
(1)web.xml文件 :

<filter>
    <filter-name>xssFilter</filter-name>
    <filter-class>com.test.filter.xssFiler</filter-class>
  </filter>
  <!-- 解决xss漏洞 -->
  <filter-mapping>
    <filter-name>xssFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

(2)Filter代码:

package com.test.filter;
import com.test.utils.XssFilterWrapper;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 作用:Xss过滤器
 * 作者:Tiddler
 * 时间:2018/11/11 10:21
 * 类名: XssFilter
 **/
public class xssFiler implements Filter {
   
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
   

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   
        //使用包装器
        System.out.println("过滤器执行了");
        XssFilterWrapper xssFilterWrapper=new XssFilterWrapper((HttpServletRequest) servletRequest);
        filterChain.doFilter(xssFilterWrapper,servletResponse);
    }

    @Override
    public void destroy() {
   

    }
}

(3)XssFilterWrapper代码:

package com.test.utils;
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * 作用:防Xss过滤器[包装器]
 * 作者:Tiddler
 * 时间:2018/11/11 10:20
 * 类名: XssFilterWrapper
 **/
public class XssFilterWrapper extends HttpServletRequestWrapper {
   
    public XssFilterWrapper(HttpServletRequest request) {
   
        super(request);
    }
    /**
     * 对数组参数进行特殊字符过滤
     */
    @Override
    public String[] getParameterValues(String name) {
   
        if("content".equals(name)){
   //不想过滤的参数,此处content参数是 富文本内容
            return super.getParameterValues(name);
        }
        String[] values = super.getParameterValues(name);
        String[] newValues = new String[values.length];
        for (int i = 0; i < values.length; i++) {
   
            newValues[i] = HtmlUtils.htmlEscape(values[i]);//spring的HtmlUtils进行转义
        }
        return newValues;
    }

}

2、看配置文件 application.properties、application.yml

(1)SpringBoot Actuator 未授权访问
在这里插入图片描述(2)配置文件中可能会存在数据库或其他组件的连接信息
Druid 登陆暴力破解
在这里插入图片描述

3、看config

在这里插入图片描述

搜索代码:WebMvcConfigurer

4、看拦截器,一般目录为interceptor

在这里插入图片描述

三、正向排查

搜索代码:@(.*?)Mapping\(

从controller接口入手,找到外部可控的参数,并跟踪参数是否传入到危险方法中

四、逆向排查

找危险函数,跟踪参数是否从外部传入,判断是否有做严格的参数校验和过滤

五、功能点审计

六、“工具”+“人工”

七、补丁对比

常见漏洞审计

一、认证和授权

1、三方组件未授权访问

①、Actuator未授权访问

白盒测试
配置文件都在src/main/resources下面,名字通常为application.yml或者
application.properties

pom依赖:spring-boot-starter-actuator
配置文件:management.endpoints

在这里插入图片描述
在这里插入图片描述/actuator/heapdump
可用jvisualvm.exe获取数据库密码
在这里插入图片描述

select s.value.toString() from java.util.Hashtable$Entry s where /password/.test(s.key.toString())
select s.value.toString() from java.lang.String s where /pass/.test(s.value.toString())
select s from java.lang.String s where /pass/.test(s.value.toString())

在这里插入图片描述获取Shirokey

org.apache.shiro.web.mgt.CookieRememberMeManager

在这里插入图片描述
整改方案
①.引入 security 依赖,打开安全限制,或禁用不需要接口

endpoints.env.enabled=false

②.去除可访问文件
在这里插入图片描述

②、Swagger未授权访问

白盒测试

pom依赖:springfox-swagger-ui

整改方案
①.加上enable(false)或者将SwaggerConfig给注释掉,弊端就是你自己也访问不了接口文档

.enable(false)

在这里插入图片描述②.添加认证授权机制: 在Swagger配置中添加认证授权机制,确保只有经过授权的用户才能访问Swagger页面。您可以使用基本身份验证、OAuth、API密钥等方式来实现认证。

③.限制访问权限: 通过配置服务器,限制只有特定IP范围或者需要登录后才能访问Swagger页面。这可以减少未经授权的访问。

④.移除生产环境不必要的Swagger文档: 如果您的应用程序是在生产环境部署的,可以考虑在生产环境中禁用Swagger文档或隐藏它以防止未经授权的访问。

③、Druid未授权访问

白盒测试

配置文件:druid

整改方案

https://www.python100.com/html/ZTO76WX5F640.html

2、登录权限绕过

①、过滤器编写不当

在这里插入图片描述在过滤器或者拦截器里获取请求,然后request.getSession(),通过请求携带的sessionID获取对应服务器上的Session,如果没有携带,则Session为null,重新创建一个Session,此时通过session里有无信息就可以判断此用户是否拥有权限
鉴权过后可以重定向到其他页面完成对应的访问或者登陆操作

例子:存在漏洞如下,只要包含路径/admin/login就可以未授权访问
在这里插入图片描述

②、拦截器编写不当

例子:漏洞主要发生于第 23 行和第 24 行,下面我们分析下漏洞成因。
首先,关键点是第 23 行,使用了 request.getRequestURI() 方法获取路径。如果使用该方法获取的路径 进行权限判断是极易出现权限绕过漏洞的。
简单来说, getRequestURI 方法返回的路径是未经过服务器端处理的原始路径,可能包含特殊字符或 路径跳转,从而绕过服务器端的安全控制。 可改成getRequestURL方法:getRequestURL()函数可以帮助获取更准确且经过处理的请求 URL,从而减少特殊字符或路径跳转等问题
其次,第 24 行使用了 uri.startsWith(“/admin”) 判断 Uri 路径中是否以 /admin 开头,以及获取并判断 Session 中的 loginUser 属性是否为 null,两个条件 && 在一起结果为 True 的话进入条件代码,提示需要登录并跳转到后台登录页面中。
既然这样,我们知道 a && b 需要两者都为 True 整体则为 True 才会进入条件判断代码中,如果另其中 一个条件为 False 则整体就为 False,就不会进入条件判断中去了。
这两个条件中,Session 部分我们是没办法操纵的。但 uri.startsWith(“/admin”) 这个条件我们可以搞点 小破坏,前面提到了 uri 是使用的 getRequestURI 方法获取的原始路径,那么我们可以找一些特殊字符 绕过路径判断,并且不影响整体接口,比如:分号 ; ,正斜杠 / 等等。
最终,构造结构路径为 /;/admin/test 或 ///admin/test ,这样路径就不是以 /admin 开头了,并且 该路径不会影响结构访问,实现了权限绕过。
在这里插入图片描述

③、shiro鉴权

在这里插入图片描述

④、Spring Security鉴权

Spring Security 可以通过 http.authorizeRequests() 开启对 web 请求进行授权保护。
url匹配
antMatchers()
使用 antMatchers 方法需要注意配置规则的顺序,配置顺序会影响授权的效果,越是具体的应该放在前面,越是笼统的应该放到后面。

antMatchers(“/cxyxj/**”).hasRole(“admin”):表示访问/cxyxj/路径的必须要有 admin 角色。
antMatchers(“/security/**”).hasRole(“user”):表示访问/security/路径的必须要有 user 角色。
.antMatchers(“/permitAll”).permitAll():表示访问/permitAll 路径不需要认证
.anyRequest().authenticated():表示除了前面定义的url,其余url访问都得认证后才能访问(登录)
and:表示结束当前标签,回到上下文 HttpSecurity,开启新一轮的配置
formLogin:开启表单登陆

@Bean
PasswordEncoder passwordEncoder() {
   
    return NoOpPasswordEncoder.getInstance();
}
 
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   
    auth.inMemoryAuthentication()
            .withUser("cxyxj")
            .password("123").roles("admin", "user")
            .and()
            .withUser("security")
            .password("security").roles("user");
}
 
@Override
protected void configure(HttpSecurity http) throws Exception {
   
 
    http.authorizeRequests()  //开启配置
            .antMatchers("/cxyxj/**").hasRole("admin")   //访问/cxyxj/**下的路径,必须具备admin身份
            .antMatchers("/security/**").hasRole("user") //访问/security/**下的路径,必须具备user身份
            .antMatchers("/permitAll").
### Java 代码审计工具推荐 #### 铲子 SAST 新一代的 Java 代码审计工具——铲子 SAST 支持主流的 Java 开发框架,采用了轻量、快捷的污点分析技术,并能支持无代码场景下的反编译扫描。此外,这款工具还提供了便捷的自定义扫描规则功能,使得开发者可以根据项目需求灵活调整审计策略[^4]。 ```java // 示例:配置自定义扫描规则 CustomRule customRule = new CustomRule(); customRule.setPattern("unsafeFunction\\(.*"); customRule.setMessage("Avoid using unsafe functions."); ``` #### 使用 JavaParser 进行静态分析 对于更细粒度的代码审查工作,可以考虑使用 `JavaParser` 库来解析并处理源码文件。通过创建 `CompilationUnit` 对象,能够深入理解程序结构并对特定部分实施针对性检测[^3]。 ```java import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; String code = "public class HelloWorld { public static void main(String[] args) {} }"; CompilationUnit cu = StaticJavaParser.parse(code); System.out.println(cu.toString()); ``` 除了上述提到的具体解决方案外,在实际操作过程中还可以借助多种类型的辅助手段提高工作效率: - **代码编辑器插件**:许多现代 IDE 如 IntelliJ IDEA 或 Eclipse 提供内置的安全检查选项以及第三方扩展包。 - **单元测试框架**:JUnit 和 TestNG 等可以帮助验证应用程序逻辑正确性和安全性。 - **反汇编/反编译软件**:当面对闭源库时尤为有用;JD-GUI 是一个流行的选择之一。 综上所述,针对不同应用场景和个人偏好可以选择合适的组合方式来进行高效的 Java 代码质量保障活动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值