基于SQL语句的数据脱敏实现方法

要解决什么

企业进行软件开发、数据分析、数据查询时,不可避免的涉及到数据安全的问题,不同人员能看到的数据不同,如何识别哪些敏感数据被查询了,或者被通过一些处理后隐性的被查询了是非常重要的。如手机号,直接判断是否查询手机号是十分容易的,但是如果查询时通过两次SQL查询,一次查询前手机号前3位,一次查询后8位,则不易被发现,数据也已泄露。本文介绍如何解决“在SQL使用中发现使用敏感数据泄露的行为”。

背景

Jsqlparser

Jsqlparser是一个用Java编写的SQL解析器,可以将SQL语句解析成语法树,方便开发人员进行SQL语句的分析和操作。目前有很多类似的SQL解析器,此类解析器只能将语句解析为语法树,但是不能使上下层结构的业务逻辑关联在一起,因而它只是一个工具,如何判断最终结果中是否涉及敏感数据的逻辑还需要我们自己编写。

安全系统

目前有一些商用的数据安全系统,包含数据脱敏功能,开源的如archery。此类系统可以识别一定类型的SQL语句,但是只包含简单结构,像包含多层嵌套查询、关联查询、函数处理、casewhen语法时,系统不能检测出。

难点

难点:无法支持复杂的嵌套查询、无法支持函数处理后的数据、无法支持casewhen语法、无法支持union关键字等。

目标

搭建一种易于扩展的SQL分析架构,能够方便的分析SQL语法树,建立上下层嵌套语句间的关系,使得SQL查询过程中能够便捷的支持各种语法,识别出可能的敏感数据泄露行为。

方法

语法树遍历

使用Jsqlparser工具将SQL解析为语法树,选择深度遍历优先算法。有两个重要概念:
一是,敏感数据的传染。
即在深度优先遍历时,先找到最底层的子句,根据from后的数据源找出本子句使用的敏感数据,如果上层父语句使用此数据,则对映数据被传染为敏感数据。
二是,敏感数据表。
即维护一个敏感数据<数据名称,来源表,来源字段>的三元组集合。一开始集合中只包含数据库中的原始字段,我们把敏感数据做一个事前的基础维护。然后在分析语法树的每层结构时,不断增加这个集合的内容,一旦某层的中间数据被传染,则加入到集合中,并记录来源。最后自下而上一层层追溯到顶端,则可以发现全部被传染的敏感数据。

实现

// 数据三元组如下
public class Col {
    public String srcTable;// 真实来源表
    public String srcCol;// 真实来源列
    public String name;// 别名
}
// 数据集合如下
private HashMap<String, Set<Col>> tableMaps = new HashMap<>();

select a.pho,b.money, (select f.name from user_friend f where f.user_id = a.id limit 1) friendName from (select pho from (select phone pho from user t1 where t1.create_time < ‘2023-05-01’) t where t.create_time > ‘2023-01-01’) a join bank b on a.id = b.user_id;为例

初始化

首先初始化中间数据集合,这些初始信息由其他系统认为设置或自动扫描识别得到,如我们设置user表的phone是敏感信息,则初始集合为Col<name:phone,srcCol:phone,srcTable:user>

使用Jsqlparse等工具解析sql为语法树,对语法树进行深度优先遍历,伪代码如下:

public void visit(PlainSelect plainSelect) {
	//accept(this)递归本方法实现深度遍历
     
	PlainSelect sub = findSub(plainSelect.getFromItem());
    sub.accept(this);

	List<Join> joins = plainSelect.getJoins();
    for (Join join : joins) {
        PlainSelect s = findSub(join.getRightItem());
        s.accept(this);
    }

	for (SelectItem selectItem : plainSelect.getSelectItems()) {
        PlainSelect sub = findSub(selectItem);
        sub.accept(this);
    }
}

第一轮

第一轮处理如下子句,根据集合得知phone为敏感数据,pho虽然重新定义了别名,但其被传染为敏感数据,则集合中增加一条Col<name:t.pho,srcCol:phone,srcTable:user>
(select phone pho from user t1 where t1.create_time < ‘2023-05-01’) t

第二轮

第二轮处理如下子句,根据上一轮集合结果,t.pho为敏感数据,则a.pho也被传染为敏感数据,则集合中增加一条Col<name:a.pho,srcCol:phone,srcTable:user>
(select pho from (select phone pho from user t1 where t1.create_time < ‘2023-05-01’) t where t.create_time > ‘2023-01-01’) a

第三轮

第三轮处理如下子句,根据上一轮集合结果,a.pho为敏感数据,则最终发现a.pho是敏感数据,依此类推。
select a.pho,b.money, (select f.name from user_friend f where f.user_id = a.id limit 1) friendName from (select pho from (select phone pho from user t1 where t1.create_time < ‘2023-05-01’) t where t.create_time > ‘2023-01-01’) a join bank b on a.id = b.user_id;

总结

1、便于逻辑分析,每次只需要解决上下相邻层间的逻辑问题,而不必跨层,大大降低了难度。
2、逻辑结构清晰,多层嵌套问题被切割成了两层语句的问题,便于后期更复杂逻辑的扩展。

  • 26
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据库SQL语句脱敏是指使用特定的函数或方法对敏感数据进行处理,以保护数据的真实性和隐私性。SQL Server提供了各种脱敏函数,可以处理不同类型的敏感数据,如字符串、数字、日期、时间、文件、图像等。 在SQL Server中,可以使用脱敏函数来实现不同的脱敏需求。例如,可以使用REPLACE函数来替换姓名中的部分字符为特定的符号,如将姓名中的第二个字符替换为星号。具体的SQL语句可以是:UPDATE table SET column = REPLACE(column, SUBSTR(column, 2, 1), '*')。 除了姓名脱敏,还可以使用其他的脱敏函数来处理其他类型的敏感数据。根据具体的需求,可以选择合适的脱敏函数,并结合其他SQL语句进行数据处理。SQL Server的脱敏技术可以帮助用户更好地处理敏感数据,保护数据的安全性和隐私性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [sql语句对数据进行脱敏](https://blog.csdn.net/u010741112/article/details/130812698)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [使用sql语句对数据库脱敏](https://blog.csdn.net/weixin_45817985/article/details/130419452)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值