Skip to content

Commit 57fd732

Browse files
hardening: migrate monitor SQL helpers to prepared variants
1 parent 8c03d47 commit 57fd732

2 files changed

Lines changed: 102 additions & 7 deletions

File tree

setup.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ function monitor_device_table_bottom() {
157157
}
158158

159159
function plugin_monitor_uninstall() {
160-
db_execute('DROP TABLE IF EXISTS plugin_monitor_notify_history');
161-
db_execute('DROP TABLE IF EXISTS plugin_monitor_reboot_history');
162-
db_execute('DROP TABLE IF EXISTS plugin_monitor_uptime');
160+
db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_notify_history');
161+
db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_reboot_history');
162+
db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_uptime');
163163
}
164164

165165
function plugin_monitor_page_head() {
@@ -203,7 +203,12 @@ function monitor_check_upgrade() {
203203

204204
$info = plugin_monitor_version();
205205
$current = $info['version'];
206-
$old = db_fetch_cell('SELECT version FROM plugin_config WHERE directory = "monitor"');
206+
$old = db_fetch_cell_prepared(
207+
'SELECT version
208+
FROM plugin_config
209+
WHERE directory = ?',
210+
['monitor']
211+
);
207212

208213
if ($current != $old) {
209214
monitor_setup_table();
@@ -319,9 +324,16 @@ function monitor_device_action_execute($action) {
319324
}
320325

321326
function monitor_device_remove($devices) {
322-
db_execute('DELETE FROM plugin_monitor_notify_history WHERE host_id IN(' . implode(',', $devices) . ')');
323-
db_execute('DELETE FROM plugin_monitor_reboot_history WHERE host_id IN(' . implode(',', $devices) . ')');
324-
db_execute('DELETE FROM plugin_monitor_uptime WHERE host_id IN(' . implode(',', $devices) . ')');
327+
if (!cacti_sizeof($devices)) {
328+
return $devices;
329+
}
330+
331+
$devices = array_map('intval', $devices);
332+
$placeholders = implode(',', array_fill(0, cacti_sizeof($devices), '?'));
333+
334+
db_execute_prepared("DELETE FROM plugin_monitor_notify_history WHERE host_id IN($placeholders)", $devices);
335+
db_execute_prepared("DELETE FROM plugin_monitor_reboot_history WHERE host_id IN($placeholders)", $devices);
336+
db_execute_prepared("DELETE FROM plugin_monitor_uptime WHERE host_id IN($placeholders)", $devices);
325337

326338
return $devices;
327339
}

tests/test_prepared_statements.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
function assert_contains(string $haystack, string $needle, string $message): void {
4+
if (strpos($haystack, $needle) === false) {
5+
fwrite(STDERR, $message . PHP_EOL);
6+
exit(1);
7+
}
8+
}
9+
10+
function assert_not_contains(string $haystack, string $needle, string $message): void {
11+
if (strpos($haystack, $needle) !== false) {
12+
fwrite(STDERR, $message . PHP_EOL);
13+
exit(1);
14+
}
15+
}
16+
17+
$setup = file_get_contents(__DIR__ . '/../setup.php');
18+
if ($setup === false) {
19+
fwrite(STDERR, "Unable to read setup.php\n");
20+
exit(1);
21+
}
22+
23+
assert_contains(
24+
$setup,
25+
"db_fetch_cell_prepared(\n\t\t'SELECT version",
26+
'Expected plugin version lookup to use db_fetch_cell_prepared().'
27+
);
28+
29+
assert_contains(
30+
$setup,
31+
"WHERE directory = ?',\n\t\t['monitor']",
32+
'Expected monitor directory lookup to use a bound placeholder.'
33+
);
34+
35+
assert_contains(
36+
$setup,
37+
"db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_notify_history');",
38+
'Expected uninstall notify-history drop to use db_execute_prepared().'
39+
);
40+
41+
assert_contains(
42+
$setup,
43+
"db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_reboot_history');",
44+
'Expected uninstall reboot-history drop to use db_execute_prepared().'
45+
);
46+
47+
assert_contains(
48+
$setup,
49+
"db_execute_prepared('DROP TABLE IF EXISTS plugin_monitor_uptime');",
50+
'Expected uninstall uptime drop to use db_execute_prepared().'
51+
);
52+
53+
assert_contains(
54+
$setup,
55+
'$placeholders = implode(\',\', array_fill(0, cacti_sizeof($devices), \'?\'));',
56+
'Expected monitor_device_remove() to build placeholder list for IN clause.'
57+
);
58+
59+
assert_contains(
60+
$setup,
61+
'db_execute_prepared("DELETE FROM plugin_monitor_notify_history WHERE host_id IN($placeholders)", $devices);',
62+
'Expected notify history delete to use db_execute_prepared() with placeholders.'
63+
);
64+
65+
assert_contains(
66+
$setup,
67+
'db_execute_prepared("DELETE FROM plugin_monitor_reboot_history WHERE host_id IN($placeholders)", $devices);',
68+
'Expected reboot history delete to use db_execute_prepared() with placeholders.'
69+
);
70+
71+
assert_contains(
72+
$setup,
73+
'db_execute_prepared("DELETE FROM plugin_monitor_uptime WHERE host_id IN($placeholders)", $devices);',
74+
'Expected uptime delete to use db_execute_prepared() with placeholders.'
75+
);
76+
77+
assert_not_contains(
78+
$setup,
79+
'db_execute(\'DELETE FROM plugin_monitor_notify_history WHERE host_id IN(\' . implode(\',\', $devices) . \')\');',
80+
'Raw notify-history delete should not remain.'
81+
);
82+
83+
echo "OK\n";

0 commit comments

Comments
 (0)