19 смертных грехов, угрожающих безопасности программ
Шрифт:
Искупление греха в Java с использованием JDBC
public static boolean doQuery(String Id) {
// пропускаем только корректные ID (от 1 до 8 цифр)
Pattern p = Pattern.compile("^\\d{1,8}$");
if (!p.matcher(arg).find)
return false;
Connection con = null;
try
{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
con = DriverManager.getConnection("jdbc:microsoft:sqlserver: " +
"//localhost:1433", "sa", "$3cre+");
PreparedStatement st = con.prepareStatement(
"exec pubs..sp_GetCreditCard ?");
st.setString(1, arg);
ResultSet rs = st.executeQuery;
while (rx.next) {
//
}
rs.close;
st.close;
}
catch (SQLException e)
{
System.out.println("Ошибка SQL");
return false;
}
catch (ClassNotFoundException e)
{
System.out.println("Ошибка во время исполнения");
return false;
}
finally
{
try
{
con.close;
} catch(SQLException e) {}
}
return true;
}
Искупление греха в ColdFusion
При работе с ColdFusion используйте cfqueryparam в теге <cfquery>, чтобы обезопасить запрос с параметрами.
Искупление греха в SQL
Не следует исполнять в хранимой процедуре строку, полученную из не заслуживающего доверия источника, как процедуру. В качестве одного из механизмов глубоко эшелонированной обороны можно воспользоваться некоторыми функциями для проверки корректности строкового параметра. В примере ниже проверяется, что входной параметр содержит ровно четыре цифры. Заметим, что длина параметра заметно уменьшена, чтобы усложнить передачу любой другой входной информации.
CREATE PROCEDURE dbo.doQuery(@id nchar(4))
AS
DECLARE @query nchar(64)
IF RTRIM(@id) LIKE \'[0-9][0-9][0-9][0-9]\'
BEGIN
SELECT @query = \'select ccnum from cust where id = \'\'\' + @id + \'\'\'\'
EXEC @query
END
RETURN
Или еще лучше – потребуйте, чтобы параметр был целым числом:
CREATE PROCEDURE dbo.doQuery(@id smallint)
В Oracle lOg, как и в Microsoft SQL Server 2005, добавлены совместимые со стандартом POSIX регулярные выражения. Поддержка регулярных выражений реализована также для DB2 и Microsoft SQL Server 2000. В MySQL регулярные выражения поддерживаются с помощью оператора REGEXP. Ссылки на все эти решения вы найдете в разделе «Другие ресурсы».
Дополнительные защитные меры
Есть много других способов уменьшить риск компрометации. Например, в РНР можно задать параметр magic_quotes_gpc=l в файле php.ini. Кроме того, запретите доступ ко всем пользовательским таблицам в базе данных, оставив только право исполнять хранимые процедуры. Это не даст противнику напрямую читать и модифицировать данные в таблицах.
Другие ресурсы
□ Writing Secure Code, Second Edition by Michael Howard and David C. LeBlanc (Microsoft Press, 2002), Chapter 12, «Database Input Issues»
□ Sarbanes–Oxley Act of 2002: www.aicpa.org/info/sarbanes–oxley_summary.htm
□ The Open Web Application Security Project (OWASP): www.owasp.org.
□ «Advanced SQL Injection in SQL Server Applications» by Chris Anley: www. nextgenss.com/papers/advanced_sql_injection.pdf
□ Web Applications and SQL Injections: www.spidynamics.com/whitepapers/ WhitepaperSQLInjection.pdf
□ «Detecting SQL Injection in Oracle» by Pete Finnigan: www.securityfocus.com/ infocus/1714
□ «How a Common Criminal Might Infiltrate Your Network» by Jes–per Johansson: www.microsoft.com/technet/technetmag/issues/2005/01 / AnatomyofaHack/default.aspx
□
«SQL Injection Attacks by Example» by Stephen J. Friedl: www.unixqiz.net/ techtips/sql–injection.html□ Oracle lOg SQL Regular Expressions:searchOracle/ downloads/1 Og_sql_regular_expressions.doc
□ «Regular Expressions in T–SQL» by Cory Koski:item.asp?itemID= 13947
□ «xp_regex: Regular Expressions in SQL Server 2000» by Dan Farino: www.codeproject.com/managed.cpp/xpregex.asp
□ SQLRegEx: www.krell–software.com/sqlregex/regex.asp
□ «DB2 Bringing the Power of Regular Expression Matching to SQL» www–106.ibm.com/developerworks/db2/library/techarticle/0301stolze/ 0301stolze.html
□ MySQL Regular Expressions: http://dev.mysql.com/doc/mysql/en/Regexp.html
□ Hacme Bank: www.foundstone.com/resources/proddesc/hacmebank.htm
Резюме
Рекомендуется
□ Изучите базу данных, с которой работаете. Поддерживаются ли в ней хранимые процедуры? Как выглядит комментарий? Может ли противник получить доступ к расширенной функциональности?
□ Проверяйте корректность входных данных и устанавливайте степень доверия к ним.
□ Используйте параметризованные запросы (также распространены термины «подготовленное предложение» и «связывание параметров») для построения SQL–предложений.
□ Храните информацию о параметрах соединения вне приложения, например в защищенном конфигурационном файле или в реестре Windows.
Не рекомендуется
□ Не ограничивайтесь простой фильтрацией «плохих слов». Существует множество вариантов написания, которые вы не в состоянии обнаружить.
□ Не доверяйте входным данным при построении SQL–предложения.
□ Не используйте конкатенацию строк для построения SQL–предложения даже при вызове хранимых процедур. Хранимые процедуры, конечно, полезны, но решить проблему полностью они не могут.
□ Не используйте конкатенацию строк для построения SQL–предложения внутри хранимых процедур.
□ Не передавайте хранимым процедурам непроверенные параметры.
□ Не ограничивайтесь простым дублированием символов одинарной и двойной кавычки.
□ Не соединяйтесь с базой данных от имени привилегированного пользователя, например sa или root.
□ Не включайте в текст программы имя и пароль пользователя, а также строку соединения.
□ Не сохраняйте конфигурационный файл с параметрами соединения в корне Web–сервера.
Стоит подумать
□ О том, чтобы запретить доступ ко всем пользовательским таблицам в базе данных, разрешив лишь исполнение хранимых процедур. После этого во всех запросах должны использоваться только хранимые процедуры и параметризованные предложения.
Грех 5. Внедрение команд
В чем состоит грех
В 1994 году автор этой главы сидел перед экраном компьютера SGI с операционной системой IRIX, на котором отображалась картинка с приглашением ввести имя и пароль. Там была возможность распечатать кое–какую документацию и указать соответствующий принтер. Автор задумался, как это могло бы быть реализовано, ввел строку, никоим образом не связанную с именем принтера, и неожиданно получил интерфейс администратора на машине, к которой у него вовсе не должно было быть доступа. Более того, он даже и не пытался войти.