MySQL 中的动态数据脱敏:无需更改应用程序即可保护敏感数据


生产数据对于日常运营至关重要,包括支持、故障排除、分析和开发。但是,当这些数据包含敏感字段,例如社会安全号码、电子邮件地址、电话号码或其他标识符时,广泛的读取权限很快就会导致不必要的风险暴露。

 

同样重要的是,许多组织在监管和合同要求下运营 ,这些要求对敏感数据的访问进行严格控制——通常包括数据脱敏, 作为履行隐私和安全义务的一部分(例如,在符合GDPRHIPAAPCI DSSSOX 和类似内部安全标准的项目中)

 

动态数据脱敏 (DDM) 现已在MySQL 9.7 LTS中正式发布,并可在MySQL企业版和OCI MySQL HeatWave中使用。借助 DDM,您可以将脱敏策略直接附加到基表列,以便MySQL在查询时根据执行用户或活动角色返回原始值或脱敏值 ,而无需更改应用程序,也无需维护单独的脱敏数据副本。

 

为什么需要动态数据脱敏

MySQL中,数据脱敏通常是通过SQL函数和/或用户自定义函数 (UDF) 结合视图来实现的。虽然这种方法有效,但通常需要:

创建和维护其他数据库对象(视图)

确保用户无法通过直接查询基表来绕过脱敏

随着库表模式的演变,持续的运维工作也在进行中。

动态数据脱敏通过在基表的列级别强制执行脱敏来简化该模型,帮助组织实施最小权限访问并减少敏感数据泄露——这是安全态势和合规性计划的重要组成部分。(与以往一样,实际合规性取决于您更广泛的控制措施、流程和配置。)

 

工作原理:
脱敏策略和gatekeeper 功能

脱敏 策略 定义为一个 CASE 表达式,其中包含:

 

gatekeeper功能:

CURRENT_USER_IN('...') 基于用户的匹配

CURRENT_ROLE_IN('...') 用于基于角色的匹配(活跃角色)

一个用于在应用脱敏时转换值的脱敏表达式(对于SSN ,我们将使用 MySQL 的内置函数 mask_ssn())

 

当查询引用一个被屏蔽的列时,MySQL 会评估网关并返回以下结果之一:

原始列值(未屏蔽),或脱敏(由策略计算得出)

由于强制执行发生在MySQL服务器内部,因此该行为在应用程序和查询路径中是一致的。

端到端示例(复制/粘贴):屏蔽除授权用户/角色以外的所有人的社会安全号码

以下是一个最小可运行示例。它展示了基于用户和基于角色的访问控制;您可以根据您的运营模式选择使用其中一种(或两种都用)

 

 

在创建脱敏策略之前,请运行
Connect as Admin
SOURCE install_component_object_policy.sql安装 Enterprise object_policy 组件;

创建、显示或删除脱敏策略的用户需要MANAGE_DATA_MASKING_POLICY权限。

 

-- Run once per server as an administrative user.

-- Requires permission to create tables in the mysql schema

-- and execute INSTALL COMPONENT.

SOURCE install_component_object_policy.sql;

 

-- Grant this to the user who will create, show, or drop masking policies.

GRANT MANAGE_DATA_MASKING_POLICY ON *.* TO '<mask_admin>'@'%';

 

0) 设置:模式 + + 示例数据

CREATE SCHEMA IF NOT EXISTS protected;

USE protected;

 

DROP TABLE IF EXISTS user_profiles;

 

CREATE TABLE user_profiles (

  id         INT PRIMARY KEY,

  first_name VARCHAR(32),

  last_name  VARCHAR(32),

  ssn        VARCHAR(16),

  zip_code   VARCHAR(10)

);

 

INSERT INTO user_profiles VALUES

  (1,'James','Smith','900-01-0001','10001'),

  (2,'Mary','Johnson','900-01-0002','90210'),

  (3,'Robert','Williams','900-01-0003','60601'),

  (4,'Patricia','Brown','900-01-0004','30301');

 

1)设置身份:用户和角色

CREATE USER IF NOT EXISTS 'seeall'@'%' IDENTIFIED BY 'Welcome_123!';

CREATE USER IF NOT EXISTS 'noseeall'@'%' IDENTIFIED BY 'Welcome_123!';

 

GRANT SELECT ON protected.user_profiles TO 'seeall'@'%';

GRANT SELECT ON protected.user_profiles TO 'noseeall'@'%';

 

CREATE ROLE IF NOT EXISTS 'pii_read'@'%';

GRANT SELECT ON protected.user_profiles TO 'pii_read'@'%';

 

GRANT 'pii_read'@'%' TO 'seeall'@'%';

 

 2)创建脱敏策略(基于用户)

CREATE MASKING POLICY mask_ssn_policy(ssn_col)

  CASE WHEN CURRENT_USER_IN('seeall')

       THEN ssn_col

       ELSE mask_ssn(ssn_col)

  END;

 

3) 将该策略应用于SSN

 ALTER TABLE protected.user_profiles

  ALTER COLUMN ssn

  SET MASKING POLICY mask_ssn_policy;


4)验证行为

SELECT id, first_name, last_name, ssn, zip_code

FROM protected.user_profiles

ORDER BY id;

由于 noseeallSSN 已被屏蔽(例如,  XXX-XX-0001)

seeall (/或拥有相应的活跃角色时)SSN 是可见的

用户noseeall”——数据已屏蔽

 

mysql> select * from user_profiles;

+----+------------+-----------+-------------+----------+

| id | first_name | last_name | ssn         | zip_code |

+----+------------+-----------+-------------+----------+

|  1 | James      | Smith     | XXX-XX-0001 | 10001    |

|  2 | Mary       | Johnson   | XXX-XX-0002 | 90210    |

|  3 | Robert     | Williams  | XXX-XX-0003 | 60601    |

|  4 | Patricia   | Brown     | XXX-XX-0004 | 30301    |

|  5 | John       | Jones     | XXX-XX-0005 | 75201    |

|  6 | Jennifer   | Garcia    | XXX-XX-0006 | 85001    |

|  7 | Michael    | Miller    | XXX-XX-0007 | 33101    |

|  8 | Linda      | Davis     | XXX-XX-0008 | 19101    |

|  9 | William    | Rodriguez | XXX-XX-0009 | 94101    |

| 10 | Elizabeth  | Martinez  | XXX-XX-0010 | 98101    |

+----+------------+-----------+-------------+----------+

10 rows in set (0.000 sec)

 用户“查看全部”数据不会被屏蔽。

 

 mysql> select * from user_profiles;

+----+------------+-----------+-------------+----------+

| id | first_name | last_name | ssn         | zip_code |

+----+------------+-----------+-------------+----------+

|  1 | James      | Smith     | 900-01-0001 | 10001    |

|  2 | Mary       | Johnson   | 900-01-0002 | 90210    |

|  3 | Robert     | Williams  | 900-01-0003 | 60601    |

|  4 | Patricia   | Brown     | 900-01-0004 | 30301    |

|  5 | John       | Jones     | 900-01-0005 | 75201    |

|  6 | Jennifer   | Garcia    | 900-01-0006 | 85001    |

|  7 | Michael    | Miller    | 900-01-0007 | 33101    |

|  8 | Linda      | Davis     | 900-01-0008 | 19101    |

|  9 | William    | Rodriguez | 900-01-0009 | 94101    |

| 10 | Elizabeth  | Martinez  | 900-01-0010 | 98101    |

+----+------------+-----------+-------------+----------+

10 rows in set (0.000 sec)

 

为什么服务器端强制执行很重要

代理层脱敏虽然有用,但它通常位于数据库前端 。如果用户直接连接到 MySQL(或以其他方式绕过代理),敏感数据仍然可能泄露。

 

动态数据脱敏MySQL内部强制执行 ,即在解析列值以执行查询时执行。这样,无论查询是通过交互式 SQL、应用程序还是数据库对象(具有预期的调用者/定义者语义)发出,都能确保脱敏的一致性。

 

适用于分析和人工智能工作负载

由于数据脱敏是在查询时应用 并由服务器强制执行的,因此动态数据脱敏还可以帮助减少下游工作流程(例如 分析提取、报告和 AI 辅助查询/代理)中敏感数据的暴露,而无需每个使用工具都实现和维护自己的脱敏逻辑。团队可以使用相同的数据集和管道,而MySQL会返回与执行身份和活动角色相适应的值。

 

了解更多/立即尝试

MySQL 9.7 发行说明:  https://dev.mysql.com/doc/relnotes/mysql/9.7/en/

试用 OCI MySQL HeatWave(免费试用)  https://www.oracle.com/heatwave/free/

 

引用官方英文文档地址:
https://blogs.oracle.com/mysql/dynamic-data-masking-in-mysql-protect-sensitive-data-without-app-changes 

分割线
感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS