Java防范SQL注入导致SQLException泄密的核心是源头切断注入路径:强制使用PreparedStatement隔离SQL结构与数据,禁用字符串拼接;异常处理时屏蔽敏感消息,仅记录标准化错误码;前置输入验证与白名单控制,并限制数据库账号权限。

Java中防范SQL注入导致的SQLException受检异常泄密,核心不是“捕获异常后隐藏堆栈”,而是从源头切断注入路径,让恶意输入根本无法触发异常——更关键的是,避免把数据库错误细节(如表名、字段名、驱动版本)通过异常消息暴露给前端或日志。
用PreparedStatement彻底隔离SQL结构与数据
SQLException本身是受检异常,但它的消息内容常含敏感信息。最根本的防护是不让注入发生,从而不触发底层数据库报错:
- 所有带用户输入的查询必须使用
PreparedStatement,禁用Statement拼接 - 占位符
?只接受参数值,不解析SQL语法,即使输入' OR 1=1 --也只会被当作字符串字面量 - 不要在SQL语句中动态拼接表名、列名、排序字段等——这些需走白名单校验或枚举控制
异常处理时不泄露数据库内部信息
即使用了PreparedStatement,其他逻辑错误仍可能抛出SQLException。此时要防止消息外泄:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 捕获
SQLException后,不直接返回e.getMessage()给前端,改用通用提示如“系统繁忙,请稍后再试” - 记录日志时,用
e.getSQLState()和e.getErrorCode()替代完整消息,它们是标准化错误码,不含敏感上下文 - 避免在日志中打印
e.printStackTrace(),尤其不能写入可被公开访问的日志文件或监控面板
输入验证+白名单机制前置拦截
预防比补救更有效。在参数进入DAO层前就过滤可疑输入:
立即学习“Java免费学习笔记(深入)”;
- 对用户名、邮箱、手机号等字段,用正则做格式校验(如
"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") - 对ID类参数(如
userId),强制转为Long.parseLong(),捕获NumberFormatException并统一处理,不留给JDBC解析机会 - 分页参数
pageNum、pageSize做范围限制(如pageSize最大设为100),避免恶意大值触发数据库超时或内存溢出
数据库权限与连接配置加固
降低异常信息的危害面:
- 应用使用的数据库账号仅授予
SELECT/INSERT/UPDATE必要权限,禁止DROP、SHOW TABLES等高危操作 - JDBC URL中添加
useSSL=true&allowPublicKeyRetrieval=false等安全参数,部分驱动支持dumpSql=false关闭调试SQL输出 - 生产环境禁用Hibernate的
show_sql=true和format_sql=true,避免日志中泄露完整语句

















