From 7a62c7d812af39a2fb8d86e02fad05a685c289cb Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 9 Feb 2026 16:26:15 +0100 Subject: [PATCH] sanity check class names before inserting into classtype tables The subsequent INSERT is done on an unqouted table name, making in theory an SQL injection through an OSM value possible. In practise this cannot happen because we check for the existance of the table. During the creation of the classtype tables there is a sanity check in place to disallow any table names that consist of anything other than alphanumeric characters. --- lib-sql/functions/placex_triggers.sql | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib-sql/functions/placex_triggers.sql b/lib-sql/functions/placex_triggers.sql index 244fe90c..3f266292 100644 --- a/lib-sql/functions/placex_triggers.sql +++ b/lib-sql/functions/placex_triggers.sql @@ -672,7 +672,7 @@ CREATE OR REPLACE FUNCTION placex_insert() AS $$ DECLARE postcode TEXT; - result BOOLEAN; + result INT; is_area BOOLEAN; country_code VARCHAR(2); diameter FLOAT; @@ -777,11 +777,12 @@ BEGIN -- add to tables for special search - -- Note: won't work on initial import because the classtype tables - -- do not yet exist. It won't hurt either. classtable := 'place_classtype_' || NEW.class || '_' || NEW.type; - SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO result; - IF result THEN + SELECT count(*) INTO result + FROM pg_tables + WHERE classtable NOT SIMILAR TO '%\W%' + AND tablename = classtable and schemaname = current_schema(); + IF result > 0 THEN EXECUTE 'INSERT INTO ' || classtable::regclass || ' (place_id, centroid) VALUES ($1,$2)' USING NEW.place_id, NEW.centroid; END IF; @@ -1337,6 +1338,7 @@ CREATE OR REPLACE FUNCTION placex_delete() AS $$ DECLARE b BOOLEAN; + result INT; classtable TEXT; BEGIN -- RAISE WARNING 'placex_delete % %',OLD.osm_type,OLD.osm_id; @@ -1395,8 +1397,12 @@ BEGIN -- remove from tables for special search classtable := 'place_classtype_' || OLD.class || '_' || OLD.type; - SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO b; - IF b THEN + SELECT count(*) INTO result + FROM pg_tables + WHERE classtable NOT SIMILAR TO '%\W%' + AND tablename = classtable and schemaname = current_schema(); + + IF result > 0 THEN EXECUTE 'DELETE FROM ' || classtable::regclass || ' WHERE place_id = $1' USING OLD.place_id; END IF;