From 4afe3e619988b0cd8067cc1d8b2d3d349c9d6664 Mon Sep 17 00:00:00 2001 From: Leo Q Date: Thu, 10 Aug 2023 21:12:19 +0800 Subject: [PATCH] =?UTF-8?q?sql=20advisor=20sql=20=E6=B3=A8=E5=85=A5?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20(#2229)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1. bump version 1.10.0 2. 登录页面调整, oidc 和钉钉登录靠前 3. sql注入修复, sql advisor 部分. * black * fix test * dbname is optional * more tests * black --- archery/__init__.py | 2 +- common/templates/login.html | 21 +++++++++++--------- requirements.txt | 8 ++++---- sql/engines/goinception.py | 3 ++- sql/engines/mysql.py | 3 ++- sql/plugins/sqladvisor.py | 25 ++++++++++++++++++++++++ sql/tests.py | 20 +++++++++++++++++++ src/init_sql/{v1.9.2.sql => v1.10.0.sql} | 2 ++ src/init_sql/v1.9.3.sql | 1 - 9 files changed, 68 insertions(+), 17 deletions(-) rename src/init_sql/{v1.9.2.sql => v1.10.0.sql} (85%) delete mode 100644 src/init_sql/v1.9.3.sql diff --git a/archery/__init__.py b/archery/__init__.py index 991b283f69..5078791cfc 100644 --- a/archery/__init__.py +++ b/archery/__init__.py @@ -1,2 +1,2 @@ -version = (1, 9, 1) +version = (1, 10, 0) display_version = ".".join(str(i) for i in version) diff --git a/common/templates/login.html b/common/templates/login.html index d5d4d81fc7..f244a9f37e 100644 --- a/common/templates/login.html +++ b/common/templates/login.html @@ -18,8 +18,20 @@
+

用户登录 +

diff --git a/requirements.txt b/requirements.txt index 8063aada18..16ea5b1cd2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,18 @@ Django==4.1.9 -mysqlclient==2.0.3 +mysqlclient==2.* requests==2.31.0 simplejson==3.17.2 mybatis_mapper2sql==0.1.9 django-auth-ldap==4.1.0 python-dateutil==2.8.1 pymongo==3.11.0 -psycopg2-binary==2.8.6 +psycopg2-binary==2.* pymysql==0.9.3 mysql-replication==0.22 django-q==1.3.9 django-redis==5.2.0 redis==3.5.3 -pyodbc==4.0.30 +pyodbc==4.* gunicorn==20.0.4 pyecharts==1.9.1 aliyun-python-sdk-rds==2.1.1 @@ -26,7 +26,7 @@ sshtunnel==0.1.5 pycryptodome==3.10.1 pyodps==0.* pandas==1.5.* -clickhouse-driver==0.2.3 +clickhouse-driver==0.* djangorestframework==3.13.1 djangorestframework-simplejwt==5.2.0 django-filter==21.1 diff --git a/sql/engines/goinception.py b/sql/engines/goinception.py index 419a866d76..d291cccf28 100644 --- a/sql/engines/goinception.py +++ b/sql/engines/goinception.py @@ -3,6 +3,7 @@ import re import traceback import MySQLdb +import pymysql import simplejson as json from common.config import SysConfig @@ -65,7 +66,7 @@ def get_backup_connection(): def escape_string(self, value: str) -> str: """字符串参数转义""" - return MySQLdb.escape_string(value).decode("utf-8") + return pymysql.escape_string(value) def execute_check(self, instance=None, db_name=None, sql=""): """inception check""" diff --git a/sql/engines/mysql.py b/sql/engines/mysql.py index 8e55464578..05252cc81a 100644 --- a/sql/engines/mysql.py +++ b/sql/engines/mysql.py @@ -2,6 +2,7 @@ import logging import traceback import MySQLdb +import pymysql import re import schemaobject @@ -100,7 +101,7 @@ def info(self): def escape_string(self, value: str) -> str: """字符串参数转义""" - return MySQLdb.escape_string(value).decode("utf-8") + return pymysql.escape_string(value) @property def auto_backup(self): diff --git a/sql/plugins/sqladvisor.py b/sql/plugins/sqladvisor.py index 28f6300c1c..698a5e7268 100644 --- a/sql/plugins/sqladvisor.py +++ b/sql/plugins/sqladvisor.py @@ -7,6 +7,8 @@ """ __author__ = "hhyo" +import re + from common.config import SysConfig from sql.plugins.plugin import Plugin @@ -17,3 +19,26 @@ def __init__(self): self.required_args = ["q"] self.disable_args = [] super(Plugin, self).__init__() + + def check_args(self, args): + result = super().check_args(args) + if result["status"] != 0: + return result + db_name = args.get("d") + if not db_name: + return result + # 防止 db_name 注入 + db_pattern = r"[a-zA-Z0-9-_]+" + if not re.match(db_pattern, db_name): + return { + "status": 1, + "msg": f"illegal db_name, only {db_pattern} is allowed", + "data": {}, + } + if db_name.startswith("-"): + return { + "status": 1, + "msg": f"illegal db_name, leading character - is not allowed", + "data": {}, + } + return result diff --git a/sql/tests.py b/sql/tests.py index 357a1ccea0..10b15839fc 100644 --- a/sql/tests.py +++ b/sql/tests.py @@ -1733,6 +1733,26 @@ def test_sqladvisor(self, _subprocess): ) self.assertEqual(json.loads(r.content)["status"], 0) + # test db_name + r = self.client.post( + path="/slowquery/optimize_sqladvisor/", + data={ + "sql_content": "select 1;", + "instance_name": "test_instance", + "db_name": "--help", + }, + ) + self.assertEqual(json.loads(r.content)["status"], 1) + r = self.client.post( + path="/slowquery/optimize_sqladvisor/", + data={ + "sql_content": "select 1;", + "instance_name": "test_instance", + "db_name": ";drop table", + }, + ) + self.assertEqual(json.loads(r.content)["status"], 1) + @patch("sql.plugins.plugin.subprocess") def test_soar(self, _subprocess): """ diff --git a/src/init_sql/v1.9.2.sql b/src/init_sql/v1.10.0.sql similarity index 85% rename from src/init_sql/v1.9.2.sql rename to src/init_sql/v1.10.0.sql index f68d2b32da..c750bed7e8 100644 --- a/src/init_sql/v1.9.2.sql +++ b/src/init_sql/v1.10.0.sql @@ -8,3 +8,5 @@ prepare stmt from @drop_sql; execute stmt; drop prepare stmt; alter table instance_account add unique index uidx_instanceid_user_host_dbname(`instance_id`, `user`, `host`, `db_name`); +--- 增加 ssl 支持 +ALTER TABLE sql_instance ADD is_ssl tinyint(1) DEFAULT 0 COMMENT '是否启用SSL'; \ No newline at end of file diff --git a/src/init_sql/v1.9.3.sql b/src/init_sql/v1.9.3.sql deleted file mode 100644 index d82c08bc42..0000000000 --- a/src/init_sql/v1.9.3.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE sql_instance ADD is_ssl tinyint(1) DEFAULT 0 COMMENT '是否启用SSL'; \ No newline at end of file