Является ли эта конкретная конкатенация пути в коде Perl пригодной для использования? - PullRequest
3 голосов
/ 14 ноября 2009

Предположим, что злоумышленник контролирует переменную $untrusted_user_supplied_path. Можно ли использовать следующий код Perl?

my $untrusted_user_supplied_path = ...
if ($untrusted_user_supplied_path =~ /\.\./) {
  die("Tries to escape homedir.");
}
my $base_path = "/home/username/";
my $full_path = "${base_path}${untrusted_user_supplied_path}";
if (-e $full_path) {
  open(FILE, "<", $full_path) || die("File not accessible.");
  while (<FILE>) {
    # present the content to the user
  }
  close(FILE);
}

Код определяется как пригодный для использования, если злоумышленник может выбрать значение $untrusted_user_supplied_path, чтобы он / она мог прочитать файл, который находится в каталоге, который не является подкаталогом $base_path (скажем, /etc/passwd )

Вы можете предположить, что код работает под Linux. Кроме того, вы можете предположить, что в коде, который представляет файл пользователю, нет дополнительных недостатков.

Обратите внимание, что вопрос заключается в том, является ли код эксплуатируемый, а не как сделать код более безопасным. Есть многочисленные способы сделать код более безопасным (например, chroot и т. д.), но это выходит за рамки этого вопроса. Просто укажите в своем ответе, если вы верить, что этот код можно использовать или нет. И конечно, пожалуйста предоставить подтверждающую аргументацию.

Ответы [ 5 ]

9 голосов
/ 14 ноября 2009

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

Безопасность - это больше, чем просто код. Вы должны учитывать среду, в которой он запускается, что еще пользователю было разрешено делать, прежде чем он запустил ваш код и т. Д. И т. Д.

Если вы действительно беспокоитесь о том, что может случиться с этим кодом, создайте матрицу рисков. Начните с той части, которая вас беспокоит, и перечислите все ее предположения. Например, в вашем случае вы можете начать с:

  • / home / username - это каталог, который я думаю (т.е. не точка монтирования, символическая ссылка, поддельный пользователь и т. Д.)
  • указанный путь является тем, который я ожидаю, и ему разрешено существовать
  • путь - обычный файл (например, не специальное устройство)
  • путь имеет определенного владельца, группу или режим
  • Я запускаю perl Я думаю, что я (нет пути атаки в поиске исполняемого файла)
  • PERL5LIB, PERL5OPT или -I не загружали пути загрузки модулей (загрузка пути при поиске модулей не выполнялась)

И так далее, и так далее. Как только вы разработаете все свои предположения, вы убедитесь, что они верны, зафиксировав эти случаи. Вы также найдете все их предположения, заблокируете их и так далее. Perl проверка порчи поможет с некоторыми из них (и я расскажу об этом более подробно в Mastering Perl ).

Успешные атаки часто являются косвенными. Например, я был частью работы по обеспечению безопасности некоторых данных в очень богатом и параноидальном банке. Мы сделали все, что могли, с помощью компьютера, и один из моих коллег в бездействующем разговоре спросил, как они справились с задачей, прежде чем мы установили сервер. Они сказали: «О, эти данные находятся на том же столе». Несмотря на всю нашу работу, их оплату, а также время и усилия каждого, каждый, кто хотел получить данные, мог буквально уйти с ним, независимо от того, что мы сделали с сервером.

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

Проблема в том, что даже лучшие люди что-то упустят. Небольшие трещины в безопасности могут показаться не столь важными, но если вы соберете достаточно, вы можете в конечном итоге оказаться в пригодной для использования ситуации. Безопасность целостна.

9 голосов
/ 14 ноября 2009

Если в homedir есть символическая ссылка на что-то снаружи, у вас все еще проблемы.

1 голос
/ 14 ноября 2009

Я собираюсь нарушить ваши правила дома и предложить вам сделать это так:

use Cwd;
my $full_path = "${canonical_base_path}${untrusted_user_supplied_path}";
my $canonical_full_path = abs_path($full_path);
if (substr($canonical_full_path, 0, length($base_path)) != $base_path) {
      die("Tries to escape homedir.");
}

Это должно быть водонепроницаемым. Для этого требуется, чтобы $ base_path был каноническим.

1 голос
/ 14 ноября 2009

Мне это кажется разумным, хотя ваш тест немного драконовский. Вы можете рассмотреть вопрос о замене:

/\.\./

с:

m{/\.\./}

, чтобы разрешить доступ к файлам и каталогам, содержащим две точки. Он по-прежнему не допускает запутанных, но потенциально допустимых обращений, таких как dir1/../dir2/filename, хотя вы можете не беспокоиться об этом.

0 голосов
/ 14 ноября 2009

Возможность использования или нет, зависит от кода, который представляет файл пользователю. В этом коде не должно быть «недостатков», так как есть возможности делать то, о чем вы даже не думали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...