第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监控异常)** ,需结合使用以提升整体安全性。

相关推荐
北冥you鱼1 小时前
OpenZeppelin Contracts 完全指南:从入门到精通,构建安全的智能合约
安全·区块链·智能合约
头茬韭菜2 小时前
4.9 SSRF 防护 — Web 工具的出站安全与私有 IP 拦截
前端·tcp/ip·安全
恒拓高科WorkPlus3 小时前
BeeWorks Meet私有化视频会议:内网会议、组织架构联动与会议安全
安全·架构
云祺vinchin3 小时前
《“医保影像云”基础规范》核心解读
安全·数据安全·容灾备份·国产化替代·医保影像云
Multipath7124 小时前
多链路聚合 + 宽带自组网 + 卫星便携站,构筑应急通信“铁三角”乾元通多链路聚合路由破局“三断”绝境,重构应急通信生命线
网络·5g·安全·智能路由器·实时音视频
yydbjx5 小时前
KACHIE发圈更隐蔽,博容安可的侧键推杆是不是不如它?
安全·求救器·防身
小五传输5 小时前
自主可控建设指南:Serv-u替代方案,实现平滑迁移业务不中断
大数据·运维·安全
HuiJingJiTuanIM7 小时前
[特殊字符]企业级IM即时通讯系统优势|稳定、安全、灵活扩展
安全·实时互动·私有化部署·私域·极光鸟·灰鲸
天天进步201517 小时前
UI-TARS 源码解析 #10:parse_action 源码解析:如何用 AST 安全解析模型生成的函数调用?
安全·ui
大耳朵-小飞象18 小时前
电力安全运维的智能密码:BACS如何破解设备全生命周期管理难题,让电网安全“看得见、管得住”?
运维·安全·智慧城市·能耗系统·楼宇智控·未来生活