'Does mogrify fix the concern with injection attacks?

I understand that psycopg2 queries should not be formed by text replacement like f-strings, %s forms, etc. for fear of injection attacks. The docs make that clear. However, what's not clear to me is if the cursor.mogrify method is subject to the same concerns.

The docs say,

-- Method: mogrify (operation[, parameters])

Return a query string after arguments binding. The string returned is exactly the one that would be sent to the database running the execute() method or similar.

https://www.psycopg.org/docs/cursor.html#cursor.mogrify

That makes it sound like execute basically runs mogrify behind the scenes. The red box talking about guns is pretty scary, though. I don't know what to trust.

Basically, if this is bad,

# don't do this even at gunpoint

my_id = 1234
my_values = ['a', 'b', 'c']


my_query = ''
for val in values:
    insert_statement = f"""INSERT INTO my_table VALUES ({my_id}, {val});"""
    my_query = '\n'.join([my_query, insert_statement])


with self.connection, self.connection.cursor() as cursor:
    cursor.execute(my_query)

is this a good substitute?

# is this a footgun?

my_id = 1234
my_values = ['a', 'b', 'c']


with self.connection, self.connection.cursor() as cursor:
    for val in values:
        my_query = cursor.mogrify("INSERT INTO my_table VALUES (%s, %s);", (my_id, val))
        cursor.execute(my_query)


Solution 1:[1]

That description is a bit misleading.

The wire protocol of PostgreSQL fully supports parametrization. A parametrized query will be sent as a "multipart" packet containing (among others) the parametrized query + the values to 'substitute' into the query.

Execution of the query is done by PostgreSQL engine, where the (parametrized) query will be tokenized, and tokens indicating substution will be substituted with actual desired values.

So, although I have never read the actual source code for psycopg, I'm quite certain that behind the scenes, cursor.execute() will leverage this native support of parametrization, and not doing a .mogrify() first.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 pepoluan