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 $$
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;