Skip to content

Commit b0a1029

Browse files
authored
fix(checkpoint-postgres): Replace f-string SQL formatting with parameterized queries in migration statements (#6328)
## Summary Replace f-string SQL formatting with parameterized queries to prevent potential SQL injection in checkpoint migration code. ## Changes Updated the migration version tracking INSERT statements in all checkpoint saver classes to use parameterized queries instead of f-string formatting: - `PostgresSaver` (libs/checkpoint-postgres/langgraph/checkpoint/postgres/__init__.py:100) - `AsyncPostgresSaver` (libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py:104-106) - `ShallowPostgresSaver` (libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py:255) - `AsyncShallowPostgresSaver` (libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py:617-619) **Before (vulnerable to SQL injection):** ```python cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})") ``` **After (using parameterized query):** ```python cur.execute("INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,)) ``` ## Risk Assessment The practical risk is low since `v` is an integer loop variable controlled by the codebase. However, using string formatting in SQL queries is a well-known anti-pattern that can lead to SQL injection vulnerabilities, especially if the code is later refactored or copied to other contexts. ## Testing - ✅ All 216 tests passing on PostgreSQL 15 and 16 - ✅ Linting and type checking passing - ✅ No functional changes to behavior
1 parent c2ef3f3 commit b0a1029

File tree

3 files changed

+8
-4
lines changed

3 files changed

+8
-4
lines changed

libs/checkpoint-postgres/langgraph/checkpoint/postgres/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def setup(self) -> None:
9797
strict=False,
9898
):
9999
cur.execute(migration)
100-
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
100+
cur.execute("INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,))
101101
if self.pipe:
102102
self.pipe.sync()
103103

libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ async def setup(self) -> None:
102102
strict=False,
103103
):
104104
await cur.execute(migration)
105-
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
105+
await cur.execute(
106+
"INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,)
107+
)
106108
if self.pipe:
107109
await self.pipe.sync()
108110

libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ def setup(self) -> None:
252252
strict=False,
253253
):
254254
cur.execute(migration)
255-
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
255+
cur.execute("INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,))
256256
if self.pipe:
257257
self.pipe.sync()
258258

@@ -614,7 +614,9 @@ async def setup(self) -> None:
614614
strict=False,
615615
):
616616
await cur.execute(migration)
617-
await cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
617+
await cur.execute(
618+
"INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,)
619+
)
618620
if self.pipe:
619621
await self.pipe.sync()
620622

0 commit comments

Comments
 (0)