sql注入防护必须用参数化查询,禁用字符串拼接;rls在分片环境易失效,权限应下沉至应用层;敏感字段须应用层加密并统一utf-8编码;审计日志需应用打标透传trace_id以串联分布式链路。

SQL 注入防护必须在应用层做,数据库中间件拦不住
分布式数据库本身不改变 SQL 注入的本质风险——恶意输入仍会拼进查询语句里。像 ShardingSphere 或 TiDB 的 proxy 层,能做简单关键词过滤,但绕过方式太多(比如用注释、大小写混写、编码变形),实际生产中不能依赖它防注入。
真正有效的做法只有一条:所有用户输入进 SQL 的地方,必须用参数化查询。不是“尽量用”,是“只要拼字符串就属于违规”。
-
PreparedStatement(Java)或pg_query_params(PHP/PgSQL)这类接口必须成为唯一出口,concat、format、+拼接字符串一律禁止 - ORM 如
MyBatis的#{}语法安全,${}是裸字符串替换,等同于拼接,高危 - 动态表名/列名无法参数化?那就白名单校验:
if table_name not in ['users', 'orders'] raise SecurityError
行级权限(RLS)在分片环境下容易失效
PostgreSQL 的 CREATE POLICY 在单库有效,但一上分片中间件(如 ShardingSphere-Proxy),策略可能只在逻辑库生效,物理节点没加载,或者分片键不在策略表达式里,导致权限漏判。
更麻烦的是,RLS 依赖 session 变量(如 current_setting('app.user_id')),而连接池和分片路由常复用连接,SET 命令可能污染后续请求。
- 优先把权限判断下沉到应用层:查前先
SELECT role FROM users WHERE id = ?,再决定是否允许访问该分片数据 - 若必须用 RLS,确保所有物理库都显式执行
CREATE POLICY,且策略中引用的字段必须是分片键或能被路由识别的字段(比如tenant_id) - 避免用
current_user或session_user做权限依据——它们在连接池场景下不可靠
敏感字段加密不能只靠数据库透明加密(TDE)
TiDB 或 MySQL 8.0 的 TDE 只加密磁盘文件,内存、网络传输、应用日志、备份文件里的明文依然存在。分布式场景下,数据跨节点复制、落盘、快照导出,暴露面更多。
华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、
真正可控的加密点只有一个:应用写入前加密,读取后解密。数据库只当二进制 blob 存。
- 用
AES-GCM而非DES或 ECB 模式,密钥由 KMS 管理,绝不硬编码 - 字段级加密需连带加密索引字段(比如手机号加密后,搜索得用加密后的值查,不能查明文)
- 注意时区与字符集:加密前统一转
UTF-8,否则不同节点解密结果可能不一致
审计日志在分布式链路里容易断掉上下文
一条 SQL 请求经过 proxy → shard node → replica,如果只在每个节点单独记 pg_log 或 slow_query_log,根本无法还原完整调用链。谁发起的?带什么 trace_id?影响哪些分片?全丢失。
必须让应用层打标,并透传到所有下游节点。
- 应用发请求前,在 SQL 注释里插入
/* trace_id=abc123, user_id=456 */,中间件和数据库需配置保留注释(sharding: props.sql-show=true不够,要解析并透传) - 数据库侧启用
log_line_prefix = '%m [%u@%d] %x ',其中%x是事务 ID,配合应用 trace_id 才能串联 - 避免用
log_statement = 'all'——高并发下 I/O 暴涨,改用'ddl'+ 慢查询日志 + 关键业务 SQL 主动埋点
最常被忽略的一点:分片键变更(比如从 user_id 改成 tenant_id)会导致旧审计日志无法关联新路由逻辑,历史数据权限追溯直接失效。上线前必须同步更新日志解析规则和归档策略。









