Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MSSQL查询脱敏的思路

MSSQL查询脱敏的思路

原创
作者头像
保持热爱奔赴山海
发布于 2024-07-19 14:09:02
发布于 2024-07-19 14:09:02
1150
举报
文章被收录于专栏:数据库相关数据库相关

这里只是个demo,查询性能还不够上生产的,仅抛砖引玉。

下面代码的核心在于引用了一个外部的jar包用于sql解析(暂未确认企业环境是否可以直接使用)。

代码语言:txt
AI代码解释
复制
# -*- coding: utf-8 -*-
# pip install pymssql==2.2.7
# pip install mysql-connector-python==8.0.31


# 这里核心是对列的解析,使用到了一个java组件 https://github.com/sqlparser/gsp_demo_java/releases/


import json
import subprocess
import time

import mysql.connector
import pymssql


def get_black_fields():
    # 需要脱敏的列清单,从数据库中获取

    mysql_db = mysql.connector.connect(
        host="192.168.31.181",
        port=3306,
        user="dts",
        passwd="123456",
        db="sql_query_platform",
    )

    mysql_cursor = mysql_db.cursor()
    mysql_cursor.execute("select field_name from mssql_masked_field where status='ON'")
    result = mysql_cursor.fetchall()

    black_fields = []
    for ii in result:
        black_fields.append(ii[0])

    print(f"当前的需要脱敏的列清单: {black_fields}")

    return black_fields


def fetch_all_as_dict(cursor):
    columns = [column[0] for column in cursor.description]
    return [dict(zip(columns, row)) for row in cursor.fetchall()]


def get_database_results(server, user, password, database, query):
    connection = pymssql.connect(server, user, password, database)
    try:
        cursor = connection.cursor()
        cursor.execute(query)
        result = fetch_all_as_dict(cursor)
    finally:
        connection.close()
    return result


# 脱敏函数
def desensitize_fields(customer_dict, fields_to_desensitize):
    desensitized_res = customer_dict.copy()
    for field in fields_to_desensitize:
        if field in desensitized_res:
            if field in fields_to_desensitize:
                desensitized_res[field] = "敏感内容不展示"

    return desensitized_res


if __name__ == "__main__":
    # 连接到业务库,执行业务数据的查询操作
    server = "192.168.31.181:2433"
    user = "sa"
    password = "Abcd1234"
    database = "testdb"

    #搞个复杂的SQL试试
    query = """
        SELECT *
        FROM (
            SELECT name as "用户名",phone as "手机号", address, remark
            FROM dbo.t1
            WHERE 1=1
        ) AS subquery;
    """

    start_ts = time.time()

    if "as".lower() in query.lower():
        # 这里还可以考虑发个钉钉告警
        # print(f"发现sql中有用到alias别名写法,请注意是否造成脱敏失败,query明细: {query}")

        with open("/tmp/tmp.sql", "w", encoding="utf-8") as f:
            f.write(str(query))

        # 计算下java解析的耗时
        start_ts_java = time.time()
        # 使用java解析列名,如果是复杂查询,可能这里比较费时间
        cmd = subprocess.Popen(
            r"/usr/local/software/jdk1.8.0_181/bin/java -jar /usr/local/Dlineage/bin/gudusoft.dlineage.jar /t mssql /f /tmp/tmp.sql /json > /tmp/json.log",
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        cmd.wait()
        stop_ts_java = time.time()

        with open("/tmp/json.log", "r", encoding="utf-8") as f:
            res = f.readlines()

        json_res = json.loads(res[0])

        relationships = json_res["relationships"]

        black_fields = get_black_fields()
        for i in relationships:
            if (i["target"]["column"] != i["sources"][0]["column"]) and i["sources"][0][
                "column"
            ] in black_fields:
                # 将找到的别名列也加进去
                black_fields.append(i["target"]["column"])

    # 获取查询结果集
    results = get_database_results(server, user, password, database, query)

    desensitized_res = [desensitize_fields(res, black_fields) for res in results]
    for ii in desensitized_res:
        # 结果转为json格式,便于前端展示
        print(json.dumps(ii, ensure_ascii=False))

    stop_ts = time.time()

    print(f"总耗时(秒): {(stop_ts - start_ts)}")
    print(f"java解析耗时(秒): {(stop_ts_java - start_ts_java)}")
    print(f"数据库查询耗时(秒): {(stop_ts - start_ts) - (stop_ts_java - start_ts_java)}")

"""
-- MySQL建表
create database sql_query_platform;
use sql_query_platform;
CREATE TABLE `mssql_masked_field` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `field_name` varchar(128) NOT NULL,
  `remark` varchar(128) NOT NULL DEFAULT '',
  `status` char(3) NOT NULL DEFAULT 'ON',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

-- 预先定义的数据
[sql_query_platform]> select * from mssql_masked_field ;
+----+------------+--------+---------+
| id | field_name | remark | status  |
+----+------------+--------+---------+
|  1 | name       |        | OFF     |
|  2 | address    |        | OFF     |
|  3 | addr       |        | OFF     |
|  4 | phone      |        | ON      |
+----+------------+--------+---------+
4 rows in set (0.00 sec)
"""
脱敏效果
脱敏效果

另外, 社区开源的druid sqlparser应该也能达到sql解析的效果,具体还有待编码测试(如果生产使用的话建议包装成http接口方式,规避掉jar包启动的耗时,不要像我上面DEMO脚本里面每次java -jar去启动)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL - MySQL++在c++11环境下接口设计
安装官方提供的mysqlconnect后,可以使用mysql++库,在官方的C API上再次做一个c++面向对象封装。 这里mysql++的安装依赖于mysql-connector-c。安装参考:http://dev.mysql.com/doc/connector-c/en/connector-c-installation-source-unix.html c++11下注意: 1.由于mysql++并没有采用c++11,所以在使用的时候报了一些警告,需要对源码进行修改。 2.在获取字段类型的API在g++
Aichen
2018/06/25
6050
Python elasticsearch 使用示例
保持热爱奔赴山海
2023/07/31
5630
闲不住,手写了数据库文档生成工具
逛博客的时候,发现了一个很有意思的文章:数据库表结构导出工具。带着好奇,我也去DIY了一个,先看看效果:
shigen
2024/04/16
1830
闲不住,手写了数据库文档生成工具
粗糙版ORM(附详细注释)
目录 ORM 其他 ORM代码 数据库表代码 mysql代码 db/models.py db/pymysql_opreator.py ORM 作为数据库表记录 和 python中对象的映射关系中间件 数据库中 python代码中 不同的表 不同的表模型类 一条条记录 一个个模型类对象 记录里的某个字段 模型类对象的属性 在python代码中通过操作orm来进行数据库的存取操作 这为简易版demo,查询条件等不够完善,仅展示实现原理 其他 焦急规划中... ORM代码 数据库表代码 数据库使用 mysql
suwanbin
2019/09/26
5160
粗糙版ORM(附详细注释)
关于 C++ 操作 MySQL 数据查询的底层数据结构与函数支持
这些天,一半的时间都花在练车了,导致毕设进度就慢下来了。而且最近完美主义越来越严重,就加了个调优的小版本。本来今天应该进入第二个阶段了(主redis),结果现在还在对第一个版本进行调优。所以目前还是主mysql。
看、未来
2021/11/24
1.1K0
如何基于Python实现MySQL查询的API设计,附上完整脚本
我们在平时的工作中不可避免会有连接到数据库的操作,通常来说我们会使用基于Shell的方式,或者基于数据库驱动的连接方式,比如JDBC,ODBC,PyMySQL,MySQLdb等。
jeanron100
2019/10/21
1.4K0
如何基于Python实现MySQL查询的API设计,附上完整脚本
MySQL版本数据备份与还原方案
在一个风和日丽的下午,姜同学正在研究动态规划算法,突然被临时传递了一个需求,大致就是测试的同学想要做自动化测试。具体的细节略过,姜同学认为需求还比较合理,可以做。要求如下: ● 无损备份线上数据库到文件 ● 支持表级备份 ● 支持字段脱敏 ● 支持版本管理 ● 支持一键还原
姜同学
2022/12/08
7690
MySQL版本数据备份与还原方案
[简约webAPI]php连接MSsql server的五种方法总结
参考了下php官方手册总结了五种PHP连接MSsql server的方法,mssql_系列函数,sqlsrv_系列函数,odbc方式连接sqlserver,PDO方式连接sqlserver,COM方式连接
landv
2020/02/11
4.3K0
[简约webAPI]php连接MSsql server的五种方法总结
python-MySQLdb的二三事
追寻 介绍 mysqldb是python操作mysql数据库的一个库.mysql的几乎所有的操作都可以实现,另外,mysqldb的一些比较的option让数据操作更符合pythonic风格.在python2系列使用Mysqldb,在python3系列使用pymysql和mysql.connect. Mysqldb的安装 下面按python2系列安装 1. pip方式安装 pip install MySQL-python 2. yum安装 sudo yum install python-mysqldb
若与
2018/04/25
2.9K1
python-MySQLdb的二三事
干货 | MSSQL 注入攻击与防御
本文所用数据库涉及SQL Server 2k5,2k8,2k12,其次对于绕过姿势和前文并无太大差别,就不做过多的讲解,主要放在后面的提权上
HACK学习
2019/08/06
1.7K0
干货 | MSSQL 注入攻击与防御
数据脱敏——基于Java自定义注解实现日志字段脱敏
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/77759844
DannyHoo
2018/09/13
6.3K0
数据脱敏——基于Java自定义注解实现日志字段脱敏
干货 | MSSQL注入和漏洞利用姿势总结
Microsoft SQL Server 是微软开发的关系型数据库管理系统。作为数据库服务器,它是一种软件产品,主要功能是根据其他软件应用程序的请求存储和检索数据,这些应用程序可以在同一台计算机上运行,也可以在网络(包括 Internet)上的另一台计算机上运行。SQL Server 默认开放的端口是 TCP 1433。
HACK学习
2023/01/03
7.1K0
干货 | MSSQL注入和漏洞利用姿势总结
开发指南,自研关键字驱动框架
框架内核是pytest,为框架提供了用例识别、组织运行、IDE集成等基础能力,以及pytest框架稳定性和强劲扩展能力。同时集成了requests等三方库,支持接口测试等。并实现了项目脚手架。
dongfanger
2023/11/11
2730
开发指南,自研关键字驱动框架
MYSQL 从项目经理的一次查询, 到PYTHON 解决问题(2) --传统企业使用MYSQL的问题
上一期的读者这个话题的读者浏览量不是太多,有点可惜了, 实际上这就是传统企业在使用MYSQL时的问题. 解决方案很多,作为上一期的续集,我想从几点来阐述一下传统企业使用MYSQL的一些问题. 1 不少传统企业的软件开发是外包性质的,外包企业都是有一些成熟的架构的,大部分企业支持的数据库的列表都包含MYSQL ,并且MYSQL也是大部分企业使用的开源数据库之一. 那问题在哪里
AustinDatabases
2021/04/22
5780
大规模异步新闻爬虫【3】:让MySQL数据库操作更方便
现如今,我们能用的数据库很多,老牌关系型数据库如MySQL(MariaDB),PostgreSQL等,新型的NoSQL数据库,还有NewSqL数据库。选择实在太多,但MySQL(Mariadb)从易获取性,易使用性,稳定性,社区活跃性方面都有较大优势,所以,我们在够用的情况下都选择MySQL的。
一墨编程学习
2019/05/14
1K0
Debezium的基本使用(以MySQL为例)
简单理解就是Debezium可以捕获数据库中所有行级的数据变化并包装成事件流顺序输出。
GreatSQL社区
2023/02/23
3.3K0
Python操作MSSQL
Python连接SQL Server数据库 - pymssql使用基础:https://www.cnblogs.com/baiyangcao/p/pymssql_basic.html
py3study
2020/01/09
3K0
用SQL代替DSL查询ElasticSearch怎样?
如果你和我一样「熟悉SQL,但不咋会写DSL」 or 「想要用SQL简化查询」,本文会介绍一下官方对ES SQL的支持,希望对你有所帮助~
用户4172423
2020/09/22
1.7K0
用SQL代替DSL查询ElasticSearch怎样?
DB离线恢复演练
作为一名DBA,需要确保数据库有备份,同时也要确保备份文件是有效的。因此需要定期对生产的备份文件进行离线恢复,验证备份文件的可用性。
保持热爱奔赴山海
2023/10/18
2740
多种语言操作MySQL
本文主要针对于Linux环境讲解,读者如果使用的是Windows,遇到问题可以一起交流。
菜菜cc
2022/11/15
3330
多种语言操作MySQL
相关推荐
MySQL - MySQL++在c++11环境下接口设计
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档