Summary
The handling of named transaction savepoints in all database implementations is vulnerable to SQL Injection as user provided input is passed directly to connection.execute(...) via f-strings.
Details
An excerpt of the Postgres savepoint handling:
async def savepoint(self, name: t.Optional[str] = None) -> Savepoint:
name = name or f"savepoint_{self.get_savepoint_id()}"
await self.connection.execute(f"SAVEPOINT {name}")
return Savepoint(name=name, transaction=self)
In this example, we can see user input is directly passed to connection.execute without being properly escaped.
All implementations of savepoints and savepoint methods directly pass this name parameter to connection.execute and are vulnerable to this. A non-exhaustive list can be found below:
Care should be given to ensuring all strings passed to connection.execute are properly escaped, regardless of how end user facing they may be.