2009-02-28 2 views
2

Я только что случайно наткнулся (на случай) на еще один глупый недостаток, вызванный неразрешенностью в sql в проекте, над которым я работаю ... и я так устал от этого.
Есть ли у вас какие-либо рекомендации относительно того, как устранить такие плохие SQL-заявления и обеспечить выполнение подготовленных заявлений, когда это возможно? Прямо сейчас я предпочел бы решение вроде Способы принуждения подготовленных заявлений

REVOKE DarnInlineDataStatements ON * TO xyz
Но так как это кажется маловероятным, есть, например. статические инструменты анализа кода для поиска этих вещей (к определенной точке надежности)? Или что-нибудь еще вы бы порекомендовали?
Редактировать: Подход с мягкими навыками ", пожалуйста, не используйте их, есть (как правило) лучшие способы", похоже, не слишком хорошо работал в прошлом. Поэтому я бы предпочел что-то, что предотвращает такие запросы в первую очередь. Не намеренно нарушать существующий код, но для будущих проектов, некоторые решения «нет таких запросов» ;-)

ответ

1

Если вы уже используете инструменты для анализа статического кода, вы можете настроить его для поиска определенных методов, например, в Java-мире Connection.createStatement вместо Connection.prepareStatement.

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

2

Вы можете просто найти свою базу кода для общих конструкций T-SQL, таких как SELECT, INSERT, UPDATE, DELETE и т. д.

Если вы используете Visual Studio 2008 Team System, существует встроенное правило анализа кода, которое будет проверять некоторые проблемы SQL. В противном случае есть бесплатный FxCop.

+0

Спасибо, я добавил FxCop в мой список дел;) – VolkerK

0

Надеюсь найти все непараметризированные запросы в вашем программном обеспечении достаточно просто. Большинство слоев доступа к базам данных, таких как PDO PHP или Perl DBI, имеют разные вызовы при подготовке запроса, чем при выполнении SQL. Выяснив, что это за вызовы и поиск кода, вы получите хорошее начало. Если вы используете Linux, grep - ваш друг.

Оттуда их крепления будут достаточно легкими (я надеюсь). Я не знаю размер проекта, но вам может потребоваться разместить запросы в общем месте или создать некоторый уровень на основе общего шаблона, такого как Active Record/DataMapper/Table Row Gateway.

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

+1

Люди, в которых я работаю, продолжают писать эти SQL-обертки. Я ненавижу обертки! Зачем нужен Perl DBI? Зачем? Зачем? Это УЖЕ ХРАМ! –

3

Если вы переместите sql в хранимые процедуры, вы можете отключить разрешения SELECT, CREATE, ALTER, UPDATE, DELETE, DROP и т. Д., Для доступа к пользователю приложения, оставив только доступ EXEC. Это предполагает SQL Server, но я уверен, что Oracle/MySQL и т. Д. Допускают подобные настройки.

Обратите также внимание, что это не гарантирует подготовленные заявления: вы все равно можете вызвать хранимую процедуру небезопасным способом. Но если вы не используете много хранимых процедур, оно найдет любое место, которое не было бы правильно закодировано, и если вы пропустите что-нибудь, это сделает очень трудным для успешной атаки на SQL-инъекцию.

+1

Если какой-либо из ваших SP когда-либо использовал динамический SQL (некоторые считают его анафемой, я обнаружил, что он имеет действующие правила использования), тогда оставление только разрешений EXEC не спасет вас от атак SQL-инъекций. –

0

У вас нет приложения отправить код непосредственно на сервер базы данных, а скорее отправить его через средний уровень. Он может легко разобрать все, что нужно отправить в БД, и наложить на него некоторые ограничения. Например, заставляя весь код SQL состоять из один и не более одного оператора, и либо отклонить его, либо выполнить только первый оператор, если их больше одного.

атаки инъекционные Basic SQL включают подобный код:

DECLARE @SQL VARCHAR(4000), @Table VARCHAR(50) 
SET @Table='Employees' -- Imagine this actually comes as a parameter from app 
SET @SQL='SELECT * FROM '[email protected] 
EXEC(@SQL) 

Атакующий может передать строку "SYSTABLES'; UPDATE BankAccount SET Деньги = Деньги + 10000 WHERE AccountCode = 12345; DROP TABLE AuditTrails;" к БД - это имело бы катастрофические последствия.

Имея средний уровень, выполняющий минимальный синтаксический анализ строк, вы защищены от этой, самой простой атаки SQL-инъекций. Для других, вы можете добавить их в среднем уровне (и это также может обрабатывать кэширование результатов, Bandwith удушение и т.д.)

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

+0

В этот момент (и мое текущее настроение) я даже подумал о том, чтобы изучить и модифицировать фактический парсер sql в postgres, mysql, ... или, возможно, _finding_ такой проект;) Есть проекты hardend для практически всего, почему бы и нет? – VolkerK

+1

Это просто неправильно. Если вы пытаетесь самостоятельно дезинфицировать струны, вы уже проиграли. –

+0

Отправка запросов непосредственно в БД является идеей * плохой *. Обработка всего через средний уровень может действительно помочь безопасности. Идея здесь заключается не в том, чтобы обезопасить строки, а скорее уменьшить (или аннулировать!) Ущерб, нанесенный такими типами инъекций SQL-инъекций. Другие атаки требуют других схем защиты. –

Смежные вопросы