第33天:安全开发-JavaEE应用&SQL预编译&Filter过滤器&Listener监听器&访问控制

一、核心知识点总览

  1. **SQL预编译(PreparedStatement)** :JavaEE中防御SQL注入的核心机制,通过固定SQL逻辑、参数化传参避免注入攻击;

  2. **Filter过滤器**:拦截Web请求/响应,实现权限控制、XSS过滤等安全功能;

  3. **Listener监听器**:监听JavaEE域对象(如Session、ServletContext)的事件,用于安全审计、内存马检测等场景。

二、SQL预编译:防御SQL注入的"安全锁"

(一)核心原理

  • **本质**:提前将SQL语句"编译成模板",用户输入仅作为"参数"填充到模板的占位符(`?`)中,不改变SQL原有执行逻辑;

  • **防注入原因**:参数会被数据库自动转义(如特殊字符`'`、`or`等),仅被识别为"数据",而非"SQL代码"。

(二)代码实现(对比不安全写法)

1. 不安全写法(Statement拼接SQL,易注入)

```java

// 风险:直接拼接用户输入,攻击者可注入 `1' union select 1,version(),database()-- `

String sql = "SELECT * FROM news WHERE id=" + userInputId;

Statement stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(sql); // 若userInputId含注入代码,SQL逻辑被篡改

```

2. 安全写法(PreparedStatement预编译)

```java

// 1. 定义SQL模板(占位符?表示参数)

String safeSql = "SELECT * FROM news WHERE id=?";

// 2. 预编译SQL(数据库提前解析逻辑,固定执行流程)

PreparedStatement pstmt = conn.prepareStatement(safeSql);

// 3. 绑定参数(第1个?赋值为userInputId,自动转义特殊字符)

pstmt.setString(1, userInputId); // 若参数是数字,用setInt(1, Integer.parseInt(userInputId))

// 4. 执行查询(逻辑已固定,注入代码无效)

ResultSet rs = pstmt.executeQuery();

// 5. 处理结果集(省略)

while (rs.next()) {

System.out.println("新闻标题:" + rs.getString("title"));

}

```

(三)安全价值

  • 从"根源"阻断SQL注入:即使攻击者输入`1' or '1'='1`,也会被当作"字符串参数"处理,SQL最终逻辑仍为"查询id等于该字符串的记录";

  • 兼容性强:所有关系型数据库(MySQL、Oracle等)均支持PreparedStatement。

三、Filter过滤器:Web请求的"拦截与守卫"

(一)核心作用

Filter是JavaEE的"请求拦截器",可在请求到达Servlet前、响应返回客户端前做自定义处理,典型安全场景:

  • 权限控制(如拦截未登录用户访问管理员页面);

  • 输入过滤(如XSS、SQL注入Payload检测);

  • 敏感信息脱敏(如响应中隐藏手机号、身份证号)。

(二)核心特性

  • **生命周期**:`init()`(应用启动时初始化,仅1次)→ `doFilter()`(每次请求触发,核心逻辑)→ `destroy()`(应用关闭时销毁,仅1次);

  • **执行流程**:请求 → Filter拦截处理 → 放行(`filterChain.doFilter()`)→ 目标Servlet/JSP → 响应 → Filter再次拦截响应 → 返回客户端。

(三)实战案例

案例1:XSS过滤(拦截含`<script>`的请求参数)

```java

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

// 注解配置:拦截访问/test路径的所有请求

@WebFilter("/test")

public class XssFilter implements Filter {

// 1. 过滤器初始化(应用启动时执行1次)

@Override

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println("XSS过滤器已初始化");

}

// 2. 核心拦截逻辑(每次请求触发)

@Override

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {

// 转换为HttpServletRequest(获取请求参数需HTTP相关对象)

HttpServletRequest request = (HttpServletRequest) req;

// 获取请求参数code(如用户输入的内容)

String code = request.getParameter("code");

// XSS检测:若含<script>标签,拦截请求

if (code != null && code.contains("<script>")) {

System.out.println("拦截XSS攻击!参数含危险标签:" + code);

resp.getWriter().write("请求含不安全内容,已拦截");

return; // 不放行,直接返回

}

// 无危险内容,放行到下一个Filter/Servlet

chain.doFilter(req, resp);

}

// 3. 过滤器销毁(应用关闭时执行1次)

@Override

public void destroy() {

System.out.println("XSS过滤器已销毁");

}

}

```

案例2:Cookie身份验证(仅允许含`user=admin`的请求访问/admin)

```java

@WebFilter("/admin") // 拦截管理员页面请求

public class AdminFilter implements Filter {

@Override

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

Cookie[] cookies = request.getCookies(); // 获取客户端Cookie

boolean isAdmin = false;

if (cookies != null) {

// 遍历Cookie,检查是否有"user=admin"

for (Cookie cookie : cookies) {

if ("user".equals(cookie.getName()) && "admin".equals(cookie.getValue())) {

isAdmin = true;

break;

}

}

}

if (isAdmin) {

chain.doFilter(req, resp); // 管理员,放行

} else {

resp.getWriter().write("非管理员,无访问权限"); // 拦截未授权请求

}

}

// init()和destroy()省略...

}

```

(四)安全场景扩展

  1. **Payload检测**:拦截含SQL注入(如`union`、`select`)、命令执行(如`;ls`)的请求参数;

  2. **权限控制**:验证请求头中的Token、Session是否有效,拦截未登录用户;

  3. **内存马相关**:红队可通过Filter植入内存马(拦截请求执行恶意代码),蓝队可通过Filter监控异常请求。

四、Listener监听器:JavaEE域对象的"事件监控器"

(一)核心作用

Listener用于"监听"JavaEE域对象的**事件**(如对象创建/销毁、属性变化),并在事件触发时执行自定义逻辑,典型场景:

  • 监控Session创建/销毁(统计在线用户数);

  • 监听ServletContext初始化(加载全局配置、初始化安全组件);

  • 安全审计(记录敏感操作的事件日志)。

(二)核心域对象与事件

| 监听器接口 | 监听对象 | 核心事件 |

| ------------ | ---------------- | --------------------------- |

| `HttpSessionListener` | HttpSession | Session创建(`sessionCreated`)、销毁(`sessionDestroyed`) |

| `ServletContextListener` | ServletContext | 应用启动(`contextInitialized`)、关闭(`contextDestroyed`) |

| `ServletRequestListener` | ServletRequest | 请求创建(`requestInitialized`)、销毁(`requestDestroyed`) |

(三)实战案例:监听Session创建与销毁

```java

import javax.servlet.annotation.WebListener;

import javax.servlet.http.HttpSessionEvent;

import javax.servlet.http.HttpSessionListener;

// 注解标记为监听器(无需web.xml配置)

@WebListener

public class SessionListener implements HttpSessionListener {

// 1. 监听Session创建(用户首次访问时触发)

@Override

public void sessionCreated(HttpSessionEvent se) {

// se.getSession():获取当前创建的Session

String sessionId = se.getSession().getId();

System.out.println("监听到新Session创建,ID:" + sessionId);

// 扩展:记录用户登录日志、统计在线用户数

}

// 2. 监听Session销毁(如调用session.invalidate()、Session超时)

@Override

public void sessionDestroyed(HttpSessionEvent se) {

String sessionId = se.getSession().getId();

System.out.println("监听到Session销毁,ID:" + sessionId);

// 扩展:清理用户临时数据、释放资源

}

}

```

配合Servlet触发Session事件

```java

// 1. 创建Session的Servlet(访问/cs触发)

@WebServlet("/cs")

public class CreateSessionServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

req.getSession(); // 获取Session(不存在则创建,触发sessionCreated)

System.out.println("Servlet创建Session");

}

}

// 2. 销毁Session的Servlet(访问/ds触发)

@WebServlet("/ds")

public class DestroySessionServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

req.getSession().invalidate(); // 销毁Session,触发sessionDestroyed

System.out.println("Servlet销毁Session");

}

}

```

(四)安全场景

  1. **代码审计**:监控Session创建/销毁事件,追踪异常会话(如短时间大量创建Session的暴力破解行为);

  2. **内存马检测**:监听ServletContext初始化事件,排查是否有未授权的恶意Listener/Filter被注入;

  3. **安全日志**:记录请求创建/销毁事件,留存访问轨迹用于事后溯源。

五、总结:三者在JavaEE安全中的协同作用

| 技术 | 核心安全能力 | 典型场景 |

| ---------------- | ------------------------------ | ----------------------------------- |

| SQL预编译 | 防御SQL注入 | 用户登录、数据查询时的参数处理 |

| Filter过滤器 | 请求拦截、权限控制、输入过滤 | XSS过滤、管理员页面访问控制 |

| Listener监听器 | 事件监控、安全审计 | 在线用户统计、Session异常行为检测 |

三者共同构成JavaEE应用的"安全三层防护":**数据层(预编译防注入)→ 请求层(Filter拦截风险)→ 事件层(Listener监控异常)** ,需结合使用以提升整体安全性。

相关推荐
Dragon online12 小时前
数据分析师成长之路--从SQL恐惧到数据掌控者的蜕变
数据库·sql
热心市民蟹不肉13 小时前
黑盒漏洞扫描(三)
数据库·redis·安全·缓存
GIS数据转换器13 小时前
综合安防数智管理平台
大数据·网络·人工智能·安全·无人机
steins_甲乙13 小时前
C++并发编程(3)——资源竞争下的安全栈
开发语言·c++·安全
2501_9159090613 小时前
iOS 反编译防护工具全景解析 从底层符号到资源层的多维安全体系
android·安全·ios·小程序·uni-app·iphone·webview
Li.CQ14 小时前
SQL学习笔记
笔记·sql·学习
Navicat中国14 小时前
Navicat 技术指引 | 面向达梦的查询工具
数据库·sql·达梦·navicat·查询
码界奇点14 小时前
医疗数据的安全长城金仓数据库如何重塑智慧医疗新生态
数据库·安全·智慧城市
lpppp小公主15 小时前
PolarCTF网络安全2025冬季个人挑战赛 wp
安全·web安全
编织幻境的妖15 小时前
SQL执行计划与优化详解
数据库·sql