@@ -255,6 +255,59 @@ def test_sqlserver_ao_metrics(
255255 aggregator .assert_metric (metric_name , value = metric_value , tags = expected_tags )
256256
257257
258+ def test_sqlserver_availability_groups_query_uses_parameterized_queries (init_config , instance_docker_metrics ):
259+ ag_with_quotes = "AG1'; DROP TABLE foo; --"
260+ instance_docker_metrics ['database_metrics' ] = {
261+ 'ao_metrics' : {'enabled' : True , 'availability_group' : ag_with_quotes },
262+ }
263+ sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
264+ metrics = SqlserverAvailabilityGroupsMetrics (
265+ config = sqlserver_check ._config ,
266+ new_query_executor = sqlserver_check ._new_query_executor ,
267+ server_static_info = STATIC_SERVER_INFO ,
268+ execute_query_handler = mock .MagicMock (),
269+ )
270+ q = metrics .queries [0 ]
271+ assert "resource_group_id = ?" in q ['query' ]
272+ assert q ['params' ] == (ag_with_quotes ,)
273+
274+
275+ def test_sqlserver_database_replication_stats_query_uses_parameterized_queries (init_config , instance_docker_metrics ):
276+ ag_with_quotes = "AG1'; DROP TABLE foo; --"
277+ instance_docker_metrics ['database_metrics' ] = {
278+ 'ao_metrics' : {'enabled' : True , 'availability_group' : ag_with_quotes },
279+ }
280+ sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
281+ metrics = SqlserverDatabaseReplicationStatsMetrics (
282+ config = sqlserver_check ._config ,
283+ new_query_executor = sqlserver_check ._new_query_executor ,
284+ server_static_info = STATIC_SERVER_INFO ,
285+ execute_query_handler = mock .MagicMock (),
286+ )
287+ q = metrics .queries [0 ]
288+ assert "resource_group_id = ?" in q ['query' ]
289+ assert q ['params' ] == (ag_with_quotes ,)
290+
291+
292+ def test_sqlserver_availability_replicas_query_uses_parameterized_queries (init_config , instance_docker_metrics ):
293+ ag_with_quotes = "AG1'; DROP TABLE foo; --"
294+ db_with_quotes = "mydb'; DROP TABLE bar; --"
295+ instance_docker_metrics ['database_metrics' ] = {
296+ 'ao_metrics' : {'enabled' : True , 'availability_group' : ag_with_quotes , 'ao_database' : db_with_quotes },
297+ }
298+ sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
299+ metrics = SqlserverAvailabilityReplicasMetrics (
300+ config = sqlserver_check ._config ,
301+ new_query_executor = sqlserver_check ._new_query_executor ,
302+ server_static_info = STATIC_SERVER_INFO ,
303+ execute_query_handler = mock .MagicMock (),
304+ )
305+ q = metrics .queries [0 ]
306+ assert "resource_group_id = ?" in q ['query' ]
307+ assert "database_name = ?" in q ['query' ]
308+ assert q ['params' ] == (ag_with_quotes , db_with_quotes )
309+
310+
258311@pytest .mark .integration
259312@pytest .mark .usefixtures ('dd_environment' )
260313@pytest .mark .parametrize ('include_ao_metrics' , [True , False ])
@@ -287,7 +340,7 @@ def test_sqlserver_availability_groups_metrics(
287340
288341 sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
289342
290- def execute_query_handler_mocked (query , db = None ):
343+ def execute_query_handler_mocked (query , db = None , params = None ):
291344 return mocked_results
292345
293346 availability_groups_metrics = SqlserverAvailabilityGroupsMetrics (
@@ -298,9 +351,9 @@ def execute_query_handler_mocked(query, db=None):
298351 )
299352
300353 if availability_group :
301- assert availability_groups_metrics .queries [0 ][ 'query' ]. endswith (
302- f" where resource_group_id = ' { availability_group } '"
303- )
354+ q = availability_groups_metrics .queries [0 ]
355+ assert " resource_group_id = ?" in q [ 'query' ]
356+ assert q . get ( 'params' ) == ( availability_group , )
304357
305358 sqlserver_check ._database_metrics = [availability_groups_metrics ]
306359
@@ -389,7 +442,7 @@ def test_sqlserver_database_replication_stats_metrics(
389442
390443 sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
391444
392- def execute_query_handler_mocked (query , db = None ):
445+ def execute_query_handler_mocked (query , db = None , params = None ):
393446 return mocked_results
394447
395448 database_replication_stats_metrics = SqlserverDatabaseReplicationStatsMetrics (
@@ -400,7 +453,8 @@ def execute_query_handler_mocked(query, db=None):
400453 )
401454
402455 if availability_group :
403- assert f"resource_group_id = '{ availability_group } '" in database_replication_stats_metrics .queries [0 ]['query' ]
456+ assert "resource_group_id = ?" in database_replication_stats_metrics .queries [0 ]['query' ]
457+ assert availability_group in database_replication_stats_metrics .queries [0 ].get ('params' , ())
404458 if only_emit_local :
405459 assert "is_local = 1" in database_replication_stats_metrics .queries [0 ]['query' ]
406460
@@ -530,7 +584,7 @@ def test_sqlserver_availability_replicas_metrics(
530584
531585 sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
532586
533- def execute_query_handler_mocked (query , db = None ):
587+ def execute_query_handler_mocked (query , db = None , params = None ):
534588 return mocked_results
535589
536590 availability_replicas_metrics = SqlserverAvailabilityReplicasMetrics (
@@ -541,11 +595,13 @@ def execute_query_handler_mocked(query, db=None):
541595 )
542596
543597 if availability_group :
544- assert f"resource_group_id = '{ availability_group } '" in availability_replicas_metrics .queries [0 ]['query' ]
598+ assert "resource_group_id = ?" in availability_replicas_metrics .queries [0 ]['query' ]
599+ assert availability_group in availability_replicas_metrics .queries [0 ].get ('params' , ())
545600 if only_emit_local :
546601 assert "is_local = 1" in availability_replicas_metrics .queries [0 ]['query' ]
547602 if ao_database :
548- assert f"database_name = '{ ao_database } '" in availability_replicas_metrics .queries [0 ]['query' ]
603+ assert "database_name = ?" in availability_replicas_metrics .queries [0 ]['query' ]
604+ assert ao_database in availability_replicas_metrics .queries [0 ].get ('params' , ())
549605
550606 sqlserver_check ._database_metrics = [availability_replicas_metrics ]
551607
@@ -1024,6 +1080,69 @@ def test_sqlserver_index_usage_metrics(
10241080 aggregator .assert_metric (metric_name , count = 0 )
10251081
10261082
1083+ def test_sqlserver_db_fragmentation_query_uses_parameterized_queries (init_config , instance_docker_metrics ):
1084+ instance_docker_metrics ['database_autodiscovery' ] = True
1085+ instance_docker_metrics ['database_metrics' ] = {
1086+ 'db_fragmentation_metrics' : {'enabled' : True , 'enabled_tempdb' : False },
1087+ }
1088+ db_with_quotes = "legit_db'; DROP TABLE foo; --"
1089+
1090+ sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
1091+
1092+ captured_queries = []
1093+
1094+ def capture_new_query_executor (queries , ** kwargs ):
1095+ captured_queries .extend (queries )
1096+ return mock .MagicMock ()
1097+
1098+ db_fragmentation_metrics = SqlserverDBFragmentationMetrics (
1099+ config = sqlserver_check ._config ,
1100+ new_query_executor = capture_new_query_executor ,
1101+ server_static_info = STATIC_SERVER_INFO ,
1102+ execute_query_handler = mock .MagicMock (),
1103+ databases = [db_with_quotes ],
1104+ )
1105+
1106+ db_fragmentation_metrics ._build_query_executors ()
1107+
1108+ assert len (captured_queries ) == 1
1109+ q = captured_queries [0 ]
1110+ assert "DB_ID(?)" in q ['query' ]
1111+ assert q ['params' ] == (db_with_quotes ,)
1112+
1113+
1114+ def test_sqlserver_db_fragmentation_object_names_uses_parameterized_queries (init_config , instance_docker_metrics ):
1115+ obj_with_quotes = "my_obj'; DROP TABLE foo; --"
1116+ instance_docker_metrics ['database_autodiscovery' ] = True
1117+ instance_docker_metrics ['database_metrics' ] = {
1118+ 'db_fragmentation_metrics' : {'enabled' : True , 'enabled_tempdb' : False },
1119+ }
1120+ instance_docker_metrics ['db_fragmentation_object_names' ] = [obj_with_quotes ]
1121+
1122+ sqlserver_check = SQLServer (CHECK_NAME , init_config , [instance_docker_metrics ])
1123+
1124+ captured_queries = []
1125+
1126+ def capture_new_query_executor (queries , ** kwargs ):
1127+ captured_queries .extend (queries )
1128+ return mock .MagicMock ()
1129+
1130+ db_fragmentation_metrics = SqlserverDBFragmentationMetrics (
1131+ config = sqlserver_check ._config ,
1132+ new_query_executor = capture_new_query_executor ,
1133+ server_static_info = STATIC_SERVER_INFO ,
1134+ execute_query_handler = mock .MagicMock (),
1135+ databases = ['master' ],
1136+ )
1137+
1138+ db_fragmentation_metrics ._build_query_executors ()
1139+
1140+ assert len (captured_queries ) == 1
1141+ q = captured_queries [0 ]
1142+ assert "IN (?)" in q ['query' ]
1143+ assert q ['params' ] == ('master' , obj_with_quotes )
1144+
1145+
10271146@pytest .mark .integration
10281147@pytest .mark .usefixtures ('dd_environment' )
10291148@pytest .mark .parametrize ('include_db_fragmentation_metrics' , [True , False ])
0 commit comments