Совет по безопасности: Параметризуйте имена параметров!

Источник: «Security Tip: Parameterise your Parameter Names!»
Ещё один пример того, почему никогда не следует доверять пользовательскому вводу!

Этот совет по безопасности, связан с недавно обнаруженной уязвимостью, которую я недавно увидел в Twitter:

Основная защита от SQL инъекций (SQLi) — это параметризация пользовательского ввода, позволяющая безопасно внедрять его в SQL запросы. Это стандартная практика, о которой постоянно говорится, и в Laravel это сделать довольно просто. На самом деле, я редко встречаю уязвимости SQLi в приложениях Laravel, потому что Eloquent достаточно мощный.

Параметризация — это стандартная практика, и все привыкли писать запросы в Laravel именно так:

$projects = Project::where('active', true)
->when($request->access_code, fn($query, $accessCode) =>
$query->where('access_code', $accessCode))
->when($request->preview_code, fn($query, $previewCode) =>
$query->orWhere('preview_code', $previewCode))
->where('created_at', '>', now()->subYear())
->get();

Однако часто упускается из виду то, что необходимо экранировать не только значения, но и имена параметров!

Рассмотрим этот код:

$firstKey = collect($request->query())->keys()->first();
$firstValue = $request->query($firstKey);

$projects = Project::where('active', true)
->where($firstKey, $firstValue)
->where('created_at', '>', now()->subYear())
->get();

Это выглядит как упрощение, чтобы не добавлять больше вложенных вызовов when(), и будет хорошо обрабатывать каждый из подобных URL:

https://example.com/projects?access_code=mellon
https://example.com/projects?preview_code=precious
https://example.com/projects?uuid=7da13f1a-b74c-4b3c-aae5-c311fd866894

Но что, если будет предоставлено:

https://example.com/projects?id=1

access_code, preview_code и uuid будут пропущены, позволяя получить доступ к первому совпавшему проекту. Затем можно перебрать ID...

Это происходит потому, что имя параметра поступает из пользовательского ввода, и ему доверяют вслепую, а доверять пользовательскому вводу никогда нельзя.

При работе с именами баз данных и столбцов таблиц рекомендую использовать список разрешённых имён и использовать значения только внутри списка. Эти вещи редко, если вообще когда-либо, бывают динамическими, и вы должны знать структуру своего приложения.

Если вам необходимо вводить в запросы динамические имена параметров, ограничьте набор символов, чтобы удалить специальные символы, убрать конфиденциальные ключевые слова и т. д. Необходимо максимально ограничить эти значения, так как это приводит к возникновению рисков. (Не говорите, что я вас не предупреждал!)

Статьи о SQL инъекциях:

Комментарии


Дополнительные материалы

Предыдущая Статья

Новые значения и функции в CSS

Следующая Статья

Проблемы экспорта по умолчанию в модулях JavaScript