19 смертных грехов, угрожающих безопасности программ
Шрифт:
□ Там, где оправдано (читай: если сомневаетесь), блокируйте файл при первом доступе к нему или в момент создания.
□ Если вы точно знаете, что файл должен быть новым и иметь нулевую длину, усекайте его. Тем самым вы предотвратите попытку противника подсунуть программе предварительно заполненный временный файл.
□ Никогда не доверяйте именам файлов, контролируемым кем–то другим.
□ Проверьте, что имя относится именно к файлу, а не к каналу, устройству или символической ссылке.
Имея все это в виду, обратимся к примерам.
Искупление греха в Perl
Пользуйтесь описателем,
#!/usr/bin/perl
my $file = "$ENV{HOME}/.config";
if (open(FILE, "< $file")) {
read_config(*FILE) if is_accessible(*FILE);
}
Искупление греха в C/C++для Unix
В некоторых системах имеется библиотечная функция realpath, существенно облегчающая вашу задачу. Но с ней связаны два «подводных камня». Во–первых, она небезопасна относительно потоков, поэтому вокруг нее придется поставить какой–то замок, если есть шанс, что функция будет вызываться из разных потоков. Во–вторых, на некоторых платформах она ведет себя неожиданно. Вот как выглядит сигнатура этой функции:
char* realpath (const char *original path, char resolved path[PATH MAX]);
В случае успеха она возвращает указатель на второй параметр, а в случае ошибки – NULL.
Идея заключалась в том, что вы передаете потенциально небезопасный путь, а функция следует по символическим ссылкам, удаляет повторяющиеся точки и т. д. Но в некоторых системах результат будет абсолютным путем, только если первый параметр – это абсолютный путь. Печально, но факт. Чтобы получить переносимый код, необходимо дописать в начало путь к текущему рабочему каталогу. Получить этот путь можно с помощью функции getcwd.
Искупление греха в C/C++для Windows
В следующем фрагменте имя файла получено от не заслуживающего доверия пользователя. Проверяется, соответствует ли оно настоящему файлу на диске; если нет, программа возвращает ошибку.
Примечание. Если хотите быть еще «круче», можете проверить также, что длина имени файла укладывается в допустимые пределы.
HANDLE hFile = CreateFile(pFullPathName,
0, 0, NULL,
OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION,
NULL);
if (hFile != INVALID_HANDLE_VALUE &&
GetFileType(hFile) == FILE_TYPE_DISK) {
// похоже на обычный файл!
}
Получение места нахождения временного каталога пользователя
Хранить временные файлы в каталоге конкретного пользователя безопаснее, чем в общедоступном месте. Получить путь к частному каталогу пользователя для хранения временных файлов можно с помощью переменной окружения ТМР.
Искупление греха в .NET
В управляемом коде, написанном на таких языках, как С# или VB.NET (в частности, в среде ASP.NET), получить имя временного файла можно, как описано ниже. В случае ASP.NET временные файлы сохраняются в каталоге, определяемом по самому процессу, в контексте которого исполняется ASP.NET.
С#
using System.IO;
string tempName = Path.GetTempFileName;
VB.NET
Imports System.IO;
Dim tempName = Path.GetTempFileName
Managed
using namespace System::IO;
String ^s = Path::GetTempFileName;
Дополнительные защитные меры
При работе с сервером Apache проверьте, чтобы в файле httpd.conf не было излишних директив FollowSymLink. Правда, когда эта директива удаляется, производительность слегка падает.
Другие ресурсы
□ «Secure programmer: Prevent race conditions» by David Wheeler: www–106. ibm.com/developerworks/linux/library/l–sprace.html?ca=dgr–lnxw07RACE
□ Building Secure Software by John Viega and Gary McGraw (Addison Wesley), Chapter 9, «Race Conditions»
□ Writing Secure Code, Second Edition by Michael Howard and David C. LeBlanc (Microsoft Press, 2002), Chapter 11 «Canonical Representation Issues»
□ Perl 5 Reference Guide в формате HTML от Рекса Суэйна: www.rexswain.com/ perl5.html#filetest
□ «Secure Programming for Linux and Unix HOWTO – Creating Secure Soft–ware» by David Wheeler: www.dwheeler.com/secure–programs/
Резюме
Рекомендуется
□ Тщательно проверяйте, что вы собираетесь принять в качестве имени файла.
Не рекомендуется
□ Не принимайте слепо имя файла, считая, что оно непременно соответствует хорошему файлу. Особенно это относится к серверам.
Стоит подумать
□ О хранении временных файлов в каталоге, принадлежащем конкретному пользователю, а не в общедоступном. Дополнительное преимущество такого решения – в том, что приложение может работать с минимальными привилегиями, поскольку всякий пользователь имеет полный доступ к собственному каталогу, тогда как для доступа к системным каталогам для временных файлов иногда необходимы привилегии администратора.
Грех 15. Излишнее доверие к системе разрешения сетевых имен
В чем состоит грех
Этот грех понятнее многих других – в большинстве реальных ситуаций у нас нет другого выхода, как доверять системе разрешения имен. В конце концов, не станете же вы запоминать, что– это IP–адрес одного из многих англоязычных серверов, доступных по имени www.google.com. И никому не хочется модифицировать файлы в своей системе, когда что–то меняется в адресации.