Вход/Регистрация
19 смертных грехов, угрожающих безопасности программ
вернуться

Виега Джон

Шрифт:

Как происходит грехопадение

Как мы сказали, есть три возможные ошибки. Глубинная причина первой – «гонки» – заключается в том, что в большинстве современных операционных систем (Windows, Linux, Unix, Max OS X и прочих) приложение не изолировано, как может показаться. В любой момент его работу может прервать другой процесс, а приложение к этому может оказаться не готовым. Другими словами, некоторые файловые операции не являются атомарными. Гонка может привести к эскалации привилегий или отказу от обслуживания из–за краха или взаимной блокировки.

Классический сценарий выглядит так: программа проверяет, существует ли файл, затем обращается к нему так, как диктует результат проверки. Примеры будут приведены ниже.

Другой вариант греха – открыть файл с переданным именем, не проверив, к чему это имя относится. В операционных системах типа Linux, Unix и Max OS X такая уязвимость проявляется обычно при неправильной работе с символическими ссылками. Программа думает, что открывает файл, тогда как на самом деле противник подсунул ей символическую ссылку. Это может привести к печальным последствиям, если процесс работает от имени пользователя root, так как root может удалить любой файл.

И наконец, противник может получить контроль над файлами, к которым обращается программа. Если приложению доступна некоторая конфиденциальная информация (например, имена других пользователей или системная база данных паролей), то вряд ли вы захотите показывать ее противнику. Наткнуться на такую ловушку можно, в частности, если приписать в начало имени файла, полученного из не заслуживающего доверия источника, некий «зашитый» в программу путь, например в случае Unix–машины – «/var/myapp/». Если библиотечные функции умеют разрешать относительные пути, то противник может подсунуть, например, такое имя: «../../etc/passwd». Это плохо, если приложению разрешено читать системные файлы, и уж совсем плохо, если оно может в них писать. Описанная техника называется «атакой с проходом по каталогам».

Греховность C/C++ в Windows

В следующем фрагменте разработчик рассчитывал на нормального пользователя, полагая, что тот укажет обычное имя файла, но забыл, что бывают и другие представители рода человеческого. Если такой код является частью серверной программы, то дело может закончиться плохо. Ведь если противник задаст имя устройства (например, порта принтера: lptl), то сервер перестанет отвечать до тех пор, пока устройство не вернет управление по тайм–ауту.

...

void AccessFile(char * szFileNameFromUser) {

HANDLE hFile =

CreateFile(szFileNameFromUsers,

0, 0,

NULL,

OPEN_EXISTING,

0,

NULL);

...

Греховность C/C++

Следующий код дает классический пример гонки за доступ к файлу. Между обращениями к access(2) и ореп(2) операционная система может переключиться на другой процесс. Если в течение этого промежутка времени файл /tmp/splat будет удален, то приложение завершится аварийно.

...

#include «sys/types.h»

#include "sys/stat.h"

#include "unistd.h"

#include "fcntl.h"

const char *filename = "/tmp/splat";

if (access(filename, R_OK) == 0) {

int fd=open(filename, O_RDONLY);

handle_file_contents(fd);

close(fd);

} else {

// обработать ошибку

}

Греховность Perl

И снова программа обращается к файлу по имени. Она определяет, разрешено ли читать файл пользователю, запустившему сценарий, и если это так, то читает его содержимое. Греховность, как и в предыдущем примере на C/C++, заключается в том, что между проверкой и чтением файл мог исчезнуть.

...

#!/usr/bin/perl

my $file = "$ENV{HOME}/.config";

read_config($file) if -r $file;

Греховность Python

А здесь ошибка не так очевидна:

...

import os

def safe_open_file(fname, base="/ver/myapp"):

# Убрать \'..\' и \'.\'

fname = fname.replace(\'../\', \'\');

fname = fname.replace(\'./\', \'\');

return open(os.path.join(base, fname))

Программа пытается воспрепятствовать атаке с проходом по каталогам. Но есть две проблемы. Во–первых, удаление недопустимых символов в данном случае представляется неверной стратегией. Если обнаружено две точки, то почему сразу не завершить программу – ведь этого не должно быть?

Во–вторых, метод replace не достигает той цели, которую поставил перед собой автор кода. Что произойдет, если противник подсунет такую строку: «…/….///»? А вот что:

□ При первом обращении к replace будут произведены две замены и останется «…///».

□ При втором обращении к replace будет произведена одна замена и останется «../».

Сюрприз!

Родственные грехи

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

  • Читать дальше
  • 1
  • ...
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: