Например приложение предоставляет пользователю возможность найти контакт по имени. Для этого читается пользовательский ввод и выполняется запрос через ContentResolver. Такую логику можно реализовать следующим образом:
val projection = arrayOf("first_name", "last_name")
val selection = "first_name = ${searchEditText.getText()}"
val result = contentResolver.query("content://my_contacts/contacts", projection, selection, null, null)
Например пользователь вводит "Ivan", тогда выполняется SQL-запрос
SELECT first_name, last_name FROM content://my_contacts/contacts WHERE first_name = Ivan.
При такой реализации злоумышленник может ввести вредоносный SQL-код в поле поиска:
nothing; DROP TABLE *;
, что приведет к запросуSELECT first_name, last_name FROM content://my_contacts/contacts WHERE first_name = nothing; DROP TABLE *;
Этот запрос удаляет все таблицы контент провайдера.
Чтобы защититься от SQL-инъекции, используется параметризованный
selection
. Для этого пишут "?
" на месте параметров в строке selection
и передают значения параметров в массиве selectionArgs
:val projection = arrayOf("first_name", "last_name")
val selection = "first_name = ?"
val selectionArgs = arrayOf(searchEditText.getText().toString())
val result = contentResolver.query("content://my_contacts/contacts", projection, selection, selectionArgs, null)
Аргументы
selectionArgs
экранируются перед выполнением SQL-запроса, поэтому описанная SQL-инъекция не сработает.