分库分表场景下sql注入更难拦截,因拆分后语句片段合法、waf/防火墙难识别;须全程参数化查询、禁用字符串拼接、严格管控${};敏感数据跨库泄露风险加剧,需脱敏存储;租户隔离易失效,须最小权限+上下文校验;审计日志碎片化,需统一trace_id注释与全局时间/id。

SQL 注入在分库分表场景下更难被拦截
分布式数据库本身不自带 SQL 注入防护,中间件(如 ShardingSphere、MyCat)或应用层的预编译逻辑一旦被绕过,恶意语句会直接落到某个物理库上执行——这时候 WAF 或数据库防火墙可能根本看不到完整 SQL,因为拆分后的语句片段看起来完全合法。
实操建议:
- 所有
WHERE条件必须用参数化查询,禁止拼接String.format()或+拼字符串 - 如果用了 MyBatis,确保
#{}占位符全覆盖;${}只允许出现在明确可控的静态枚举字段名场景(如排序字段),且需白名单校验 - ShardingSphere 的
sql-show配置打开后会打印重写前原始 SQL,可用于审计,但生产环境必须关掉——它不记录参数值,日志里全是问号,无法判断是否被注入
分布式事务中敏感数据跨库泄露风险被放大
当一笔订单涉及用户库 + 交易库 + 积分库,而事务日志(如 Seata 的 undo_log)或补偿任务把明文手机号、身份证号写进跨库消息体时,任意一个下游库被攻破,就等于全链路敏感字段裸奔。
实操建议:
- 禁止在
undo_log表、MQ 消息体、调度任务参数中存任何 PII(个人身份信息)明文,改用脱敏 ID 或哈希索引(如HMAC-SHA256(uid, secret)) - Seata AT 模式默认不加密日志,若业务强依赖事务一致性,需自行扩展
UndoLogManager实现字段级加密写入 - 分库键(sharding key)尽量避开敏感字段:别用
id_card或phone做分片依据,否则攻击者可通过高频查询试探出分片映射关系,再定向爆破某库
权限隔离在多租户分库架构中极易失效
很多团队以为“每个租户一个库”就天然隔离了数据,结果 DBA 给应用账号分配的是 tenant_1.* 和 tenant_2.* 全库权限,而应用代码里又没做租户上下文校验——只要篡改请求头里的 X-Tenant-ID,就能越权查别人库。
华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、
实操建议:
- 数据库账号按最小权限原则,只授予单库
SELECT/INSERT/UPDATE,禁用DROP、SHOW DATABASES、跨库JOIN权限 - 在 DAO 层强制绑定租户上下文:每次执行
SELECT前检查ThreadLocal.getTenantId()是否与当前 SQL 所属库匹配,不匹配直接抛AccessDeniedException - ShardingSphere 的
HintManager支持强制路由,但若用setDatabaseShardingValue()动态切库,必须配合租户鉴权,否则等于开放库级跳转入口
审计日志在分库环境下难以关联还原完整行为
用户 A 修改了订单状态,这个操作可能触发主库写订单表、从库更新统计表、异步服务写日志库——三处日志时间戳不同、traceID 不一致、没有全局事务 ID 关联,安全团队查入侵路径时只能看到碎片化动作。
实操建议:
- 所有数据库访问统一走封装好的
DBTemplate,在执行前注入trace_id到注释(如/* trace_id=abc123 */ UPDATE order SET status=2),MySQL 的general_log或代理层能捕获该注释 - 避免用
SELECT NOW()记录操作时间,改用应用层生成统一request_time并透传到各库,否则跨机房时钟漂移会导致日志顺序错乱 - 不要依赖 MySQL 自增 ID 做行为排序,分库后 ID 不连续也不全局有序,得靠业务侧生成单调递增的
sequence_id或使用TinyID等分布式发号器
真正麻烦的不是技术方案多难实现,而是每个分库组件(JDBC 驱动、分片中间件、ORM、监控埋点)都在自己那一层悄悄绕过安全约定——得挨个对齐,不能只信文档里写的“默认安全”。









