From cc1c7de7b3230a6dd793c7ab5a5802d36b3592f9 Mon Sep 17 00:00:00 2001 From: tuanaiseo Date: Fri, 3 Apr 2026 19:40:34 +0700 Subject: [PATCH] fix(security): sql injection risk from dynamic sql identifier con `insert_rows` concatenates `table` (and likely `cols`) directly into SQL strings. If these values can be influenced by untrusted input, an attacker can inject SQL through identifiers. Affected files: utils.py Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com> --- mbid_mapping/mapping/utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mbid_mapping/mapping/utils.py b/mbid_mapping/mapping/utils.py index f457708471..c863aacd20 100755 --- a/mbid_mapping/mapping/utils.py +++ b/mbid_mapping/mapping/utils.py @@ -2,6 +2,7 @@ from time import asctime import psycopg2 +from psycopg2 import sql from psycopg2.extras import execute_values from psycopg2.errors import OperationalError @@ -27,11 +28,17 @@ def insert_rows(curs, table, values, cols=None): Helper function to insert a large number of rows into postgres in one go. ''' + if not isinstance(table, str) or not table: + raise ValueError("table must be a non-empty string") + + table_sql = sql.SQL('.').join(sql.Identifier(part) for part in table.split('.')) + if cols is not None and len(cols) > 0: - query = "INSERT INTO " + table + " (" + ",".join(cols) + ") VALUES %s" + cols_sql = sql.SQL(',').join(sql.Identifier(col) for col in cols) + query = sql.SQL("INSERT INTO {} ({}) VALUES %s").format(table_sql, cols_sql) execute_values(curs, query, values, template=None) else: - query = "INSERT INTO " + table + " VALUES %s" + query = sql.SQL("INSERT INTO {} VALUES %s").format(table_sql) execute_values(curs, query, values, template=None)