描述“连接池复用”在多租户下的安全风险。
解读
在国内公有云或金融云场景里,一个 Cloud SQL 实例常被多个业务线(租户)共用,以节省成本。连接池(HikariCP、Druid、Spring 默认池)会把物理连接缓存下来反复使用,只要 TCP 不断、会话变量未重置,下一次复用就仍带着上一次的上下文。如果池层不做“租户级隔离”,就会出现 A 租户残留的 Session 变量、临时表、角色、SET 指令甚至 cursor 状态被 B 租户直接继承,导致越权、数据污染或审计轨迹错乱。面试官想听的是:你能否把“连接复用”与“多租户”这两个维度叠加,把风险场景、攻击路径、Google Cloud SQL 的缓解机制都说清楚。
知识点
- 租户隔离模型:国内常见“共享实例+独立库/schema”模式,IAM 只到实例级,库内仍靠自建用户体系。
- MySQL 会话污染:
SET @user_id = 10086这类用户变量在连接归还后不会自动清零;SQL SECURITY DEFINER的临时存储过程也可留在内存。 - PostgreSQL 会话污染:
SET SESSION AUTHORIZATION、SET role、SET search_path会一直保持到显式RESET或连接关闭;临时表ON COMMIT PRESERVE ROWS跨事务存活。 - Cloud SQL 自带机制:
- Cloud SQL Auth Proxy 的 IAM 鉴权每次走 OAuth2 令牌,令牌换人不复用同一物理连接,天然阻断跨租户复用。
- 私有 IP + 自建池时,Google 不再做会话级重置,风险落到应用侧。
- 国内合规:《个人信息保护法》第 38 条要求“采取必要措施确保境外接收方处理活动达到本法保护水平”,若池复用导致日志错位,审计失效即视为违规。
答案
在 Cloud SQL 多租户场景下,连接池复用带来的核心风险是**“会话上下文残留导致横向越权”**。
具体表现三步走:
① 身份残留:A 租户业务通过 SET SESSION AUTHORIZATION 或 SET role 提升为 rdsAdmin 后归还连接,池未重置,B 租户拿到同一连接即拥有管理员权限。
② 数据残留:A 租户创建的 ON COMMIT PRESERVE ROWS 临时表或 MySQL 用户变量仍可见,B 租户可直接 SELECT 到上一租户的敏感中间结果。
③ 审计错位:Cloud SQL 的 pgAudit 或 MySQL Audit Plugin 以“连接 ID”为线索,若连接 ID 复用,监管部门看到的日志主体将错误地指向最后一个复用者,导致溯源失败,违反等保 2.0 对审计完整性的要求。
缓解手段:
- 优先使用 Cloud SQL Auth Proxy,每次新令牌强制建立新连接,彻底避免复用;
- 若必须用私有 IP+自建池,在归还连接前显式执行“会话重置脚本”:
- MySQL:
RESET SESSION VARIABLES; DROP TEMPORARY TABLES; - PostgreSQL:
RESET ALL; SET SESSION AUTHORIZATION DEFAULT; CLOSE ALL;
- MySQL:
- 按租户拆池,最小化连接混用;
- 打开 Cloud SQL 的
cloudaudit.googleapis.com/data_access日志,并在应用侧把租户 ID 注入到application_name,实现双层审计对齐。
拓展思考
面试官可能追问:“如果租户量级达到万级,拆池会耗尽实例连接上限,怎么办?”
可答:
- 采用 “分池+令牌桶”混合模式:把租户哈希到 64 个池,每个池上限 20 连接,用 Guava RateLimiter 做二次流控,既控制总连接数,又把同一租户尽可能落到同一池,降低交叉概率;
- 利用 Cloud SQL 新推出的“Pooler”预览版(基于 PgBouncer 改造),支持 “事务级重置”,每次事务结束自动
DISCARD ALL,比应用层重置更轻量; - 最终架构:Proxy 池负责“身份隔离”,Cloud SQL Pooler 负责“会话隔离”,两层叠加可在万租户场景下把越权风险降到 <0.01%,同时保持 QPS 提升 30% 的运维收益。