Я работал над защитой своего приложения:
q = "insert into foo (name, descr, some_fk_int) values ($${}$$, $${}$$, $${}$$);".format(
name.replace("$$",""),
description.replace("$$",""),
str(fkToAnotherTable).replace("$$","") if fkToANotherTable is not None else 'NULL'
)
cur.execute(q)
Я заметил, что при этом он попытается вставить строку NULL в БД в целочисленную запись. Ради сохранения единообразия я в значительной степени брал все строки, обрабатывающие это таким образом, и все целые, преобразовывая в строку, а затем делая это (просто покрывая базы).
Это работало, когда этобыло просто:
.... ($$Tony$$,$$Bar$$, NULL)
но теперь, когда это:
.....($$Tony$$, $$Bar$$, $$NULL$$)
, это не удалось. Я думал, что есть способ реализовать это единообразно. Я делал это потому, что, когда выполнял поиск по индексам, я заметил, что он понимает целые числа как строки
select * from foo where id = $$id$$
Так что я закрывал приложение, где пользовательский ввод собирался поместить в базы данных. Я мог бы удалить его из ints, но я подумал, что было бы разумно, если бы кто-то попытался передать строку в int, чтобы увидеть «что произойдет».
Я думал, что запрос потерпит неудачу, если идентификаторбыл int, и вы сделали:
select * from foo where id = $$hello$$
, но я думал о более интересных случаях, когда кто-то попробует sqlinjection
select * from foo where id = $$$$ or 1=1$$$$
, где введенная строка была: $$ or 1=1$$
. Я думал, что мог бы решить это, приведя к строке, а затем заменив ключевые символы. НО в процессе внедрения или выбора я замечал случай NULL и пытался выяснить, как его обойти?
Может быть, мне следует настроить запрос, чтобы сделать что-то вроде:
q = "insert into foo (name, description, fk) values
( $${}$$, $${}$$, {} );".format(
name.replace("$$",""),
description.replace("$$",""),
"$${}$$".format(str(FK).replace("$$","")) if FK is not None else "NULL"
)
вместо этого, который только добавляет $$
, если это не None? Тогда это будет работать.
TLDR: есть ли способ, позволяющий передать 'NULL' в поле int, и он понимает его как ноль?
Edit : Кажетсякак будто люди думали, что я должен следовать параметризованным определениям запросов, выполненным в psycopg2 под вторым свойством функции выполнения Курсора.
Я не был уверен, решит ли это SQL-инъекцию, но я думал сделать что-то следующее:
q = "select * from foo where name in ({}) and user_id = %s".format(
",".join(["%s" for d in my_list])
)
# creates: select * from foo where name in (%s, %s, %s, %s, %s) and user_id = %s;
args = [d for d in my_list] + [user_id]
# creates [1,2,3,4,5,7493]
cursor.execute(q, args)
, так как веб-сайт позволяет второму аргументу быть последовательностью, списком или диктовкой.