Сведения о вопросе

Electro Full

10:37, 16th August, 2020

Теги

c#   .net   php   sql   parsing    

Лучший подход к разбору для SQL в PHP файлов?

Просмотров: 444   Ответов: 6

Для моей старшей диссертации я разработал программу, которая будет автоматически обнаруживать и предлагать исправления уязвимостей SQL инъекций с использованием подготовленных инструкций. В частности, расширение mysqli для PHP. Мой вопрос для сообщества SO заключается в следующем: каков ваш предпочтительный подход к обнаружению SQL в исходном коде PHP?

Я использовал перечисление, содержащее SQL keywords (SELECT, INSERT, ...) , и в основном анализировал каждую строку, повторяя перечисление, чтобы определить, присутствует ли какой-либо SQL. Кроме того, я должен был убедиться, что синтаксический анализатор не ошибочно обнаруживает html (например <\select>).

Для меня это решение работало нормально, но теперь у меня есть немного больше времени на руках и я подумал о рефакторинге кода, чтобы использовать более элегантное (и эффективное) решение. Пожалуйста, ограничьте свои решения использованием C# , поскольку это то, в чем я написал свою программу.



  Сведения об ответе

P_S_S

01:28, 16th August, 2020

Ваше решение кажется мне прекрасным. Другой способ состоял бы в том, чтобы разобрать файл PHP с помощью синтаксического анализатора Lex/Yacc, используя grammar для PHP, есть один хороший инструмент разбора C# grammar под названием Coco/R http://www.ssw.uni-linz.ac.at/coco/ .

Однако я считаю, что если вы все же разберете язык, то в конечном итоге потратите слишком много времени (на разработку и вычисление) без каких-либо дополнительных результатов.

Я бы придерживался вашего оппортунистического подхода, но протестируйте его на различных кодах PHP и настройте его, чтобы охватить все возможные случаи.


  Сведения об ответе

pumpa

15:47, 20th August, 2020

Может быть, есть некоторый пробел в разборе текстовых строк против BNF для, скажем, SQL92, и оценка каждой строки на том, насколько близко фрагменты соответствуют grammar.

Хотя звучит это как тяжелая работа. Ваш простой подход позволит поймать уже такой большой процент реальных случаев.


  Сведения об ответе

+-*/

03:51, 5th August, 2020

Я не знаю специфики переменных в C#, так что вам придется простить меня или проголосовать против использования PHP, но 70% из времени, когда мой запрос SQL входит в переменную, как это

$sql = "SELECT * FROM table;";

Кроме того, я не могу придумать ничего, что вы могли бы сделать, чтобы улучшить то, что у вас уже есть.

Учитываете ли вы операторы, которые создаются по нескольким строкам и используют переменные внутри строки? (Пример ниже)

$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname";


  Сведения об ответе

PHPH

11:22, 11th August, 2020

Я бы сказал, что было бы лучше искать вызовы функций, а не искать сам SQL. Возможно, измените синтаксический анализатор PHP для поиска вызовов функций, которые приводят к выполнению запроса SQL, который не является подготовленным запросом.


  Сведения об ответе

nYU

06:32, 26th August, 2020

Я не знаю специфики переменных в C#, так что вам придется простить или опустить голос за использование PHP, но 70% из времени, когда мой запрос SQL входит в переменную, похожую на эту..

Да, мой первоначальный подход состоял в том, чтобы просто искать $sql vars, так как это то, что используют большинство людей, но после тестирования против нескольких приложений PHP я быстро выбросил это решение, потому что некоторые разработчики используют некоторые фанковые имена переменных ...

Учитываете ли вы операторы, которые создаются по нескольким строкам и используют переменные внутри строки? (Пример ниже)

Да. Я также пытался обрабатывать утверждения, которые были созданы условно, но это не всегда получалось так хорошо. ;)


  Сведения об ответе

darknet

04:50, 4th August, 2020

Простой regex для обнаружения всех операторов CRUD sql, используемых с функциями (предполагая, что $script содержит весь сценарий php)

preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?\)\s*?;/is', 
               $script, $matches);

Он должен соответствовать всем возможным операторам SELECT, INSERT, UPDATE, DELETE, если они заключены в круглые скобки и двойные кавычки. Он не учитывает регистр и должен соответствовать утверждениям, которые также охватывают несколько строк.

отредактируйте #1: Regex для сопоставления CRUD операторов, подобных назначениям строк;

preg_match_all('/\$\w+\s*?=\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?;/is', 
               $script, $matches);

редактировать #2:

// $variable detecting version of #1 regex
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?(?:\$\w+){1}.*?"\s*?\)\s*?;/is', 
                   $script, $matches);


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться