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.
This commit is contained in:
Sarah Hoffmann
2026-02-09 16:26:15 +01:00
parent 615804b1b3
commit 7a62c7d812

View File

@@ -672,7 +672,7 @@ CREATE OR REPLACE FUNCTION placex_insert()
AS $$ AS $$
DECLARE DECLARE
postcode TEXT; postcode TEXT;
result BOOLEAN; result INT;
is_area BOOLEAN; is_area BOOLEAN;
country_code VARCHAR(2); country_code VARCHAR(2);
diameter FLOAT; diameter FLOAT;
@@ -777,11 +777,12 @@ BEGIN
-- add to tables for special search -- 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; classtable := 'place_classtype_' || NEW.class || '_' || NEW.type;
SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO result; SELECT count(*) INTO result
IF result THEN 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)' EXECUTE 'INSERT INTO ' || classtable::regclass || ' (place_id, centroid) VALUES ($1,$2)'
USING NEW.place_id, NEW.centroid; USING NEW.place_id, NEW.centroid;
END IF; END IF;
@@ -1337,6 +1338,7 @@ CREATE OR REPLACE FUNCTION placex_delete()
AS $$ AS $$
DECLARE DECLARE
b BOOLEAN; b BOOLEAN;
result INT;
classtable TEXT; classtable TEXT;
BEGIN BEGIN
-- RAISE WARNING 'placex_delete % %',OLD.osm_type,OLD.osm_id; -- RAISE WARNING 'placex_delete % %',OLD.osm_type,OLD.osm_id;
@@ -1395,8 +1397,12 @@ BEGIN
-- remove from tables for special search -- remove from tables for special search
classtable := 'place_classtype_' || OLD.class || '_' || OLD.type; classtable := 'place_classtype_' || OLD.class || '_' || OLD.type;
SELECT count(*)>0 FROM pg_tables WHERE tablename = classtable and schemaname = current_schema() INTO b; SELECT count(*) INTO result
IF b THEN 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; EXECUTE 'DELETE FROM ' || classtable::regclass || ' WHERE place_id = $1' USING OLD.place_id;
END IF; END IF;