Как я вручаю изображение с Perl с некоторой безопасностью и наименьшим количеством ресурсов?

Между прочим, можно подробно остановиться на этой идее очень, быстро находят два уникальные числа среди списка дубликатов.

Позволяют нам назвать уникальные числа a и b. Сначала возьмите XOR всего как предложенный Kyle. То, что мы получаем, является a^b. Мы знаем a^b! = 0, с тех пор a! = b. Выберите любой 1 бит a^b и использование что как маска - более подробно: выберите x в качестве питания 2 так, чтобы x & (a^b) является ненулевым.

Теперь разделяет список на два подсписка - один подсписок содержит все числа y с y& x == 0, и остальные входят в другой подсписок. По тому, как мы выбрали x, мы знаем, что a и b находятся в различных блоках. Мы также знаем, что каждая пара дубликатов находится все еще в том же блоке. Таким образом, мы можем теперь применить Вас olde "XOR-em-all" прием к каждому блоку независимо и обнаружить то, что a и b полностью.

Обман.

5
задан brian d foy 13 October 2009 в 22:19
поделиться

6 ответов

  1. If you're going to use extension as a substitute for MIME-type, then you'd better name all your JPEG images .jpeg and not .jpg! File::MMagic or File::MimeInfo would make better general-purpose solutions.
  2. (stat $file)[10] isn't the content-length, it's the ctime, which is worthless to you. (stat $file)[7] works, but -s $file works just as well and it's obvious to any Perl programmer what it does without having to consult the stat manual. (2a: use -s on the filehandle once you open it instead of the filename to avoid racing against file replacement.)
  3. I can access any file on the filesystem that's readable by the user the CGI runs as, e.g. image.pl?image=../../../../../../../etc/passwd. I'd suggest specifically mentioning the images directory so that you're not dependent on the getcwd, and using File::Spec->no_upwards and File::Spec->catfile to build a pathname that can only be inside the images directory.
  4. It's not really good form for a CGI to die if it's avoidable. If the file isn't found, return a 404 status. If the request is illegal, return a 400 or 403 status, etc.
  5. Your URLs would be nicer if you used path_info to allow image.pl/foo.png instead of image.pl?img=foo.png.
  6. Unless you add some more logic, the images you serve up won't be cached by the client.
  7. Man, these are stacking up. Have you considered finding some code that's already written for the purpose instead of writing your own?
5
ответ дан 13 December 2019 в 05:38
поделиться

Посмотрите, как это делается в Apachegallery

http://metacpan.org/pod/Apache::Gallery

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

4
ответ дан 13 December 2019 в 05:38
поделиться

The simplest way to serve an image is by using the file handling that is probably already included in your webserver.

You can also add authentication by using an .htaccess file (if you're using Apache).

1
ответ дан 13 December 2019 в 05:38
поделиться

Я думаю, вам здесь что-то не хватает:

my @img = $query->param;
if ( $_ eq "img" ) { my $file = $query->param($_); }
if ( $_ ne "img" ) {    ## error }

$ _ не инициализирован. Я думаю, вы хотели сказать:

my @img = $query->param;
foreach (@img) {
  if ( $_ eq "img" ) { my $file = $query->param($_); }
  if ( $_ ne "img" ) {    ##  error }
}

или для лучшей читаемости и удобства обслуживания

my @img = $query->param;
foreach my $param (@img) {
  if ( $param eq "img" ) { my $file = $query->param($param); }
  if ( $param ne "img" ) {    ## error }
}

С другой стороны, вы, вероятно, захотите использовать

( stat($file) )[7];

, а не

( stat($file) )[10];

, чтобы получить длину файла. (stat $ file) [10] даст вам время изменения файла.

1
ответ дан 13 December 2019 в 05:38
поделиться

Я бы изменил только несколько вещей.

Во-первых, замените блок кода после первого блока комментариев следующим:

my $query = new CGI;
my $file = $query->params('img');

Ваш код для получения расширения файла не работает для меня. Это значит:

my ($ext) = $file =~ m/\.([^\.]+)$/;

Я не понимаю использования "my $ image = do {...". Это просто не кажется необходимым.

Поскольку вы уже используете модуль CGI, используйте его для создания ваших заголовков за вас:

print $query->header(
    -type => 'image/' . $ext,
    -Content_length => $length,
    );

То, как вы читаете файл и записываете его обратно, выглядит функционально идеально.

У меня есть несколько дополнительных комментариев и предложений. Во-первых, ваш код крайне небезопасен. Приятно, что вы думаете о режиме заражения, но вы ничего не делаете с именем файла, переданным от вашего клиента. Что, если они прошли "/ etc / passwd", например? Во-вторых, вы можете открыть файл изображения (после дополнительных проверок безопасности) перед отправкой заголовков HTTP. Это позволит вам отправить клиенту разумную ошибку (404?), А не просто умереть. Используйте метод «заголовка» CGI, чтобы упростить это. Вы все еще можете написать что-нибудь в STDERR, если хотите.

Это все, о чем я сейчас могу думать. Надеюсь, этого достаточно, чтобы вы начали.

1
ответ дан 13 December 2019 в 05:38
поделиться

Я не уверен, что вы пытаетесь сделать, но похоже, что с этим было бы намного проще справиться без Perl и CGI. Какой сервер вы используете? Я бы предпочел исправить это с помощью правила перезаписи в Apache.

Я никогда не был поклонником скриптов привратника. Может быть, если вы скажете, почему вы пытаетесь это сделать, мы сможем предложить хорошее решение (а не просто лучшее :).

0
ответ дан 13 December 2019 в 05:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: