From 3b2828033342266459bd98cd9496d45df8e2a605 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sun, 15 Nov 2026 11:36:49 +0100 Subject: [PATCH] fix: Escapes generated SQL and validates sequence number create_camera_update_statements.php wrote OSM tag keys and values unescaped into /migrations/*.sql. Values are now escaped and node ids cast to int. The sequence number argument must be numeric and is bound as a parameter instead of being concatenated into SQL and the output path. --- .../utils/create_camera_update_statements.php | 40 +++++++++++++------ data_handler/utils/update_camera.php | 12 +++++- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/data_handler/utils/create_camera_update_statements.php b/data_handler/utils/create_camera_update_statements.php index cf18dfc..a2a072c 100755 --- a/data_handler/utils/create_camera_update_statements.php +++ b/data_handler/utils/create_camera_update_statements.php @@ -2,6 +2,18 @@ include "config.php"; +$seqNum = $_SERVER['argv'][1] ?? ''; +if (!ctype_digit($seqNum)) { + echo "Invalid sequence number\n"; + exit(1); +} + +// Quote a value for the generated SQL file. Values come from OSM data and are untrusted. +function sqlString($value) { + global $mysqli; + return "'" . $mysqli->real_escape_string((string) $value) . "'"; +} + $elementTypes = array(); $count = 0; $countDelete = 0; @@ -91,7 +103,7 @@ function endElement ($parser, $name) { $mode = ''; } else if ($name == 'node') { if ($mode == 'delete') { - $id = $curNodeAttrs['id']; + $id = (int) $curNodeAttrs['id']; if (! $deleteTagStmt->execute()) { echo "***** Error : Deleting tags $id : ". $deleteTagStmt->error . "\n"; @@ -119,7 +131,7 @@ function endElement ($parser, $name) { - $id = $curNodeAttrs['id']; + $id = (int) $curNodeAttrs['id']; if ($mode == 'modify') { if (! $deleteTagStmt->execute()) { @@ -140,36 +152,36 @@ function endElement ($parser, $name) { $k = 'lat'; $v = $curNodeAttrs['lat']; - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; $k = 'lon'; $v = $curNodeAttrs['lon']; - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; $k = 'userid'; $v = $curNodeAttrs['user']; - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; $k = 'version'; $v = $curNodeAttrs['version']; - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; $k = 'timestamp'; $v = $curNodeAttrs['timestamp']; - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; foreach($curNodeTags as $k => $v) { - $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, '$k', '$v');\n"; + $sql_statement = $sql_statement . "INSERT INTO tag (id, k, v) VALUES ($id, " . sqlString($k) . ", " . sqlString($v) . ");\n"; } } else if ($mode == 'modify') { // delete former surveillance nodes that were modified to non-surveillance nodes - $id = $curNodeAttrs['id']; + $id = (int) $curNodeAttrs['id']; if (! $deleteTagStmt->execute()) { echo "***** Error : Deleting tags $id for non-surveillance node : ". $deleteTagStmt->error . "\n"; @@ -208,11 +220,13 @@ while ($data = fread($fp, 4096)) { } } -$sql="UPDATE sync_state SET v='" . $_SERVER['argv'][1] ."' WHERE k='sequenceNumber';"; -$mysqli->query($sql); -$sql_statement = $sql_statement . "UPDATE sync_state SET v='" . $_SERVER['argv'][1] ."' WHERE k='sequenceNumber';\n"; +$syncStmt = $mysqli->prepare("UPDATE sync_state SET v=? WHERE k='sequenceNumber'"); +$syncStmt->bind_param('s', $seqNum); +$syncStmt->execute(); +$syncStmt->close(); +$sql_statement = $sql_statement . "UPDATE sync_state SET v='" . $seqNum ."' WHERE k='sequenceNumber';\n"; $sql_statement = $sql_statement . "COMMIT;"; -$sql_file = "/migrations/".$_SERVER['argv'][1].".sql"; +$sql_file = "/migrations/".$seqNum.".sql"; file_put_contents($sql_file, $sql_statement); $mysqli->close(); diff --git a/data_handler/utils/update_camera.php b/data_handler/utils/update_camera.php index dc88e48..539e0ca 100755 --- a/data_handler/utils/update_camera.php +++ b/data_handler/utils/update_camera.php @@ -2,6 +2,12 @@ include "config.php"; +$seqNum = $_SERVER['argv'][1] ?? ''; +if (!ctype_digit($seqNum)) { + echo "Invalid sequence number\n"; + exit(1); +} + $elementTypes = array(); $count = 0; $countDelete = 0; @@ -281,8 +287,10 @@ while ($data = fread($fp, 4096)) { } } -$sql="UPDATE sync_state SET v='" . $_SERVER['argv'][1] ."' WHERE k='sequenceNumber';"; -$mysqli->query($sql); +$syncStmt = $mysqli->prepare("UPDATE sync_state SET v=? WHERE k='sequenceNumber'"); +$syncStmt->bind_param('s', $seqNum); +$syncStmt->execute(); +$syncStmt->close(); $mysqli->commit(); printDebug();