java代码审计基础

UWI Lv3

javase

动态加载字节码

使用defineClass 加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.reflect.Method;
import java.util.Base64;
public class HelloDefineClass {
public static void main(String[] args) throws Exception {
Method defineClass =
ClassLoader.class.getDeclaredMethod("defineClass", String.class,
byte[].class, int.class, int.class);
defineClass.setAccessible(true);
byte[] code =
Base64.getDecoder().decode("yv66vgAAADQAGwoABgANCQAOAA8IABAKABEAEgcAEwcAFAEA
Bjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApTb3VyY2VGaWxlAQAKSGVs
bG8uamF2YQwABwAIBwAVDAAWABcBAAtIZWxsbyBXb3JsZAcAGAwAGQAaAQAFSGVsbG8BABBqYXZh
L2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3Ry
ZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5n
OylWACEABQAGAAAAAAABAAEABwAIAAEACQAAAC0AAgABAAAADSq3AAGyAAISA7YABLEAAAABAAoA
AAAOAAMAAAACAAQABAAMAAUAAQALAAAAAgAM");
Class hello =
(Class)defineClass.invoke(ClassLoader.getSystemClassLoader(), "Hello", code,
0, code.length);
hello.newInstance();
}
}

使用URLClassLoader加载

1
2
3
4
5
6
7
8
9
10
11
12
import java.net.URL;
import java.net.URLClassLoader;
public class HelloClassLoader
{
public static void main( String[] args ) throws Exception
{
URL[] urls = {new URL("http://localhost:8000/")};
URLClassLoader loader = URLClassLoader.newInstance(urls);
Class c = loader.loadClass("Hello");
c.newInstance();
}
}

动态代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 1. 定义接口
interface UserService {
void addUser(String name);
void deleteUser(String name);
}

// 2. 实现接口的实际类
class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户: " + name);
}

@Override
public void deleteUser(String name) {
System.out.println("删除用户: " + name);
}
}

// 3. 实现调用处理器(InvocationHandler)
class LoggingHandler implements InvocationHandler {
private Object target; // 被代理的对象

public LoggingHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在方法调用前添加日志
System.out.println("开始执行方法: " + method.getName());

// 调用实际对象的方法
Object result = method.invoke(target, args);

// 在方法调用后添加日志
System.out.println("方法执行完成: " + method.getName());

return result;
}
}

// 4. 测试类
public class DynamicProxyDemo {
public static void main(String[] args) {
// 创建实际对象
UserService realService = new UserServiceImpl();

// 创建调用处理器,传入实际对象
InvocationHandler handler = new LoggingHandler(realService);

// 创建动态代理对象
UserService proxyService = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(), // 类加载器
new Class[]{UserService.class}, // 代理的接口
handler // 调用处理器
);

// 通过代理对象调用方法
System.out.println("=== 通过代理调用方法 ===");
proxyService.addUser("张三");
System.out.println();
proxyService.deleteUser("李四");

System.out.println("\n=== 直接调用方法 ===");
// 对比直接调用实际对象的方法
realService.addUser("王五");
}
}

springboot

cookie与session

1
2
3
4
5
6
7
8
9
10
 Cookie cookie = new Cookie(name, value);
cookie.setMaxAge(maxAge);
cookie.setPath("/");

// 添加Cookie到响应
response.addCookie(cookie);


HttpSession session = request.getSession(true);
session.setAttribute(key, value);

java filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

@WebFilter("/*")
public class LoggingFilter implements Filter {

private FilterConfig filterConfig;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
System.out.println("LoggingFilter初始化完成");
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
String remoteAddr = request.getRemoteAddr();
Date timestamp = new Date();

// 记录请求开始时间
long startTime = System.currentTimeMillis();

// 输出请求信息到控制台
System.out.println("[" + timestamp + "] 请求开始: " + requestURI + " from " + remoteAddr);

// 执行后续过滤器或Servlet
chain.doFilter(request, response);

// 计算请求处理时间
long processingTime = System.currentTimeMillis() - startTime;

// 输出请求完成信息
System.out.println("[" + new Date() + "] 请求完成: " + requestURI +
" 处理时间: " + processingTime + "ms");
}

@Override
public void destroy() {
System.out.println("LoggingFilter销毁");
}
}

jwt

1
2
3
4
5
6
Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + REFRESH_EXPIRATION_TIME))
.signWith(SECRET_KEY)
.compact();

Interceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.example.demo.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class DemoInterceptor implements HandlerInterceptor {

private static final Logger logger = LoggerFactory.getLogger(DemoInterceptor.class);

// 在Controller方法执行之前调用
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);

String requestURI = request.getRequestURI();
String clientIP = request.getRemoteAddr();
logger.info(">>> preHandle: Request URL=[{}], Client IP=[{}]", requestURI, clientIP);

// 认证检查示例(简单版)
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
logger.warn("Access denied: Missing or invalid token");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
return false; // 中断请求,不再调用Controller
}
// 可以在这里解析Token并将用户信息放入request attribute,供Controller使用
// request.setAttribute("userInfo", parsedUserInfo);

return true; // 继续执行,调用下一个拦截器或Controller
}

// 在Controller方法执行之后,视图渲染之前调用
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.info(">>> postHandle: Request handled successfully.");
// 可以对ModelAndView进行修改
}

// 在整个请求完成之后调用(视图渲染完毕)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;

String requestURI = request.getRequestURI();
logger.info(">>> afterCompletion: Request URL=[{}], Time Taken=[{}ms]", requestURI, executeTime);

if (ex != null) {
logger.error("Request processing failed with exception: ", ex);
}
}
}

注册拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.demo.config;

import com.example.demo.interceptor.DemoInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private DemoInterceptor demoInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(demoInterceptor)
.addPathPatterns("/api/**") // 拦截所有以 /api 开头的路径
.excludePathPatterns("/api/public/**", "/api/auth/login"); // 排除特定的公开路径
}
}

拦截器与过滤器执行顺序

image-20250822162416181

aop

image-20250822164902257

image-20250822171042375

image-20250822172540088

image-20250822172910816

切入点表达式的几种写法

image-20250822173501023

image-20250822174026608

常用注解

注解类别 主要注解 用途
启动类 @SpringBootApplication 主启动注解
配置类 @Configuration, @Bean 配置Bean定义
组件 @Component, @Service, @Repository, @Controller 组件声明
依赖注入 @Autowired, @Qualifier, @Primary 依赖管理
Web @RestController, @GetMapping, @PostMapping Web控制器
事务 @Transactional 事务管理
测试 @SpringBootTest, @MockBean 测试支持
条件 @ConditionalOnProperty, @Profile 条件化配置
AOP @Aspect, @Around 切面编程
调度 @Scheduled 定时任务
1
@ModelAttribute 将 HTTP 请求参数(表单数据、查询参数)绑定到一个 Java 对象
  • Title: java代码审计基础
  • Author: UWI
  • Created at : 2025-08-18 14:18:15
  • Updated at : 2025-08-31 09:28:25
  • Link: https://nbwsws.github.io/2025/08/18/代码审计/java代码审计基础/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments