直接SELECT *会泄露敏感字段,因视图仅是预定义查询、不自动脱敏;必须在视图中显式用数据库特有函数(如MySQL的REGEXP_REPLACE、PG的overlay)对phone和id_card字段做字符级脱敏,并严格控制权限禁止直查原表。

为什么直接 SELECT * 会泄露敏感字段
视图本身不加密、不拦截,只是预定义的查询语句。如果底层表含 phone 或 id_card 字段,而视图里没做处理,用户查视图就跟查原表一样拿到明文——这是最常见的“以为安全了,其实全暴露”场景。
关键点在于:视图的字段必须显式声明脱敏逻辑,不能依赖应用层后处理;否则权限再严,SELECT * FROM user_view 仍可能返回原始号码。
- MySQL 8.0+ 可用
REGEXP_REPLACE或字符串函数遮掩中间位 - PostgreSQL 推荐用
overlay()+repeat()控制掩码长度 - SQL Server 要注意
LEN()对 Unicode 的兼容性,避免截断错误
手机号脱敏:保留前3后4,中间用*替代
不同数据库写法差异大,核心是别硬编码位置,要适配不同长度(如带国际区号的 11 位或 12 位)。
MySQL 示例(兼容 11 位国内手机号):
CREATE VIEW safe_user AS
SELECT
id,
REGEXP_REPLACE(phone, '^(1[3-9])\d{4}(\d{4})$', '$1****$2') AS phone,
name,
created_at
FROM user_table;PostgreSQL 更稳妥的做法是先判断长度再替换:
CREATE VIEW safe_user AS
SELECT
id,
CASE
WHEN LENGTH(phone) = 11 THEN overlay(phone placing '****' from 4 for 4)
ELSE phone
END AS phone,
name,
created_at
FROM user_table;- 别用
SUBSTR(phone, 1, 3) || '****' || SUBSTR(phone, -4)—— PostgreSQL 中SUBSTR(..., -4)在老版本不支持 - Oracle 用户注意:
SUBSTR负数起始位行为和 PG 不同,需改用RPAD(SUBSTR(phone,1,3), LENGTH(phone)-4, '*') || SUBSTR(phone,-4) - 若业务存在 12 位带 86 前缀的号码,建议先清洗再进视图,或加正则分支判断
身份证脱敏:只显示前6后4,校验位不能动
身份证最后一位可能是 X,且第 18 位是校验码,必须保留;前6位是地址码,后4位含出生年月,这两段有业务价值,中间应隐藏。
通用写法(适用于 MySQL/PG/SQL Server):
CREATE VIEW safe_user AS SELECT id, CONCAT(LEFT(id_card, 6), '******', RIGHT(id_card, 4)) AS id_card, phone, name FROM user_table;
但要注意:LEFT/RIGHT 在 SQL Server 和 MySQL 5.7+ 支持,PG 需换成 SUBSTR(id_card, 1, 6) 和 SUBSTR(id_card, LENGTH(id_card)-3)。
- 别用
REPLACE(id_card, SUBSTR(id_card,7,8), '********')—— 若身份证含重复子串(如 '111111'),会误替换 - 如果字段允许 NULL,
CONCAT在 MySQL 中遇 NULL 返回 NULL,建议套COALESCE(id_card, '') - 某些审计要求“不可逆”,所以不能用哈希;此处纯字符替换,符合多数等保二级场景
权限控制必须配合视图才真正生效
建好视图只是第一步。用户能查视图,不代表他不能绕过——比如直接查原表,或用 INFORMATION_SCHEMA.COLUMNS 发现真实字段名。
- 务必
REVOKE SELECT ON user_table FROM 'app_user'@'%',只授SELECT ON safe_user - PostgreSQL 还要
REVOKE USAGE ON SCHEMA public FROM app_user,防止跨 schema 查原表 - MySQL 8.0 启用角色(
CREATE ROLE safe_reader)比直接授权更易维护 - 测试时用实际账号登录执行
SELECT * FROM user_table,确认报错ERROR 1142 (42000): SELECT command denied
最易被忽略的是:视图依赖的函数(如自定义脱敏 UDF)若未授权 EXECUTE,视图会创建成功但查询时报错 execute command denied,这个错误不提示具体缺哪个权限,得逐个检查函数权限。

















