|
3 | 3 | import os |
4 | 4 | import platform |
5 | 5 | import urllib.parse |
6 | | -from decimal import Decimal |
7 | 6 | from datetime import timedelta |
| 7 | +from decimal import Decimal |
8 | 8 | from typing import Optional |
9 | 9 |
|
10 | 10 | import oracledb |
|
32 | 32 | from fastapi import HTTPException |
33 | 33 | from apps.db.es_engine import get_es_connect, get_es_index, get_es_fields, get_es_data_by_http |
34 | 34 | from common.core.config import settings |
| 35 | +import sqlglot |
| 36 | +from sqlglot import expressions as exp |
35 | 37 |
|
36 | 38 | try: |
37 | 39 | if os.path.exists(settings.ORACLE_CLIENT_PATH): |
@@ -464,6 +466,9 @@ def convert_value(value): |
464 | 466 | def exec_sql(ds: CoreDatasource | AssistantOutDsSchema, sql: str, origin_column=False): |
465 | 467 | while sql.endswith(';'): |
466 | 468 | sql = sql[:-1] |
| 469 | + # check execute sql only contain read operations |
| 470 | + if not check_sql_read(sql): |
| 471 | + raise ValueError(f"SQL can only contain read operations") |
467 | 472 |
|
468 | 473 | db = DB.get_db(ds.type) |
469 | 474 | if db.connect_type == ConnectType.sqlalchemy: |
@@ -569,3 +574,29 @@ def exec_sql(ds: CoreDatasource | AssistantOutDsSchema, sql: str, origin_column= |
569 | 574 | "sql": bytes.decode(base64.b64encode(bytes(sql, 'utf-8')))} |
570 | 575 | except Exception as ex: |
571 | 576 | raise Exception(str(ex)) |
| 577 | + |
| 578 | + |
| 579 | +def check_sql_read(sql: str, dialect=None): |
| 580 | + try: |
| 581 | + |
| 582 | + statements = sqlglot.parse(sql, dialect=dialect) |
| 583 | + |
| 584 | + if not statements: |
| 585 | + raise ValueError("Parse SQL Error") |
| 586 | + |
| 587 | + write_types = ( |
| 588 | + exp.Insert, exp.Update, exp.Delete, |
| 589 | + exp.Create, exp.Drop, exp.Alter, |
| 590 | + exp.Merge, exp.Command |
| 591 | + ) |
| 592 | + |
| 593 | + for stmt in statements: |
| 594 | + if stmt is None: |
| 595 | + continue |
| 596 | + if isinstance(stmt, write_types): |
| 597 | + return False |
| 598 | + |
| 599 | + return True |
| 600 | + |
| 601 | + except Exception as e: |
| 602 | + raise ValueError(f"Parse SQL Error: {e}") |
0 commit comments