Adobe Reader онлайн не читает все PDF? - PullRequest
1 голос
/ 16 января 2012

Как видно из названия, я сделал скрипт для чтения PDF-файлов. Только конкретные файлы могут быть открыты. Все файлы, которые были изменены до 29-09-2008, могут быть открыты. Все файлы после не могут.

Вот мой код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Stienser Omroeper</title>
</head>

<body>

<?php
$file = 'E:/Omrop/'.$_GET['y'].'/'.$_GET['f'];
$filename = $_GET['f'];

header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
@readfile($file);
?>
</body>
</html>

$ _GET содержит y (год для структуры карты) и f (имя файла). Если я открою $ file after и воспользуюсь ссылкой на моем компьютере, она будет работать отлично. В браузере я получаю сообщение Этот файл поврежден и не может быть восстановлен ..

У кого-нибудь есть идеи?

1 Ответ

1 голос
/ 17 января 2012

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

Что если вы работаете в системе Unix?Что произойдет, если кто-то отправит ?y=&f=../../../etc/passwd?

Это даже не затрагивает тот факт, что вы не проводите никакой очистки для желаемого имени пользователя файла.Пользователь может представить полностью поддельные данные и получить полностью поддельное имя файла.

Этот код не выполняет проверку ошибок, и даже явно отключает ошибки при выдаче файла пользователю, используя readfile.Это корень вашей проблемы.Никто не знает, что происходит.

Итак, мы можем это исправить.

Перво-наперво, вы захотите провести некоторую проверку y и f.Вы упомянули, что y - это год, поэтому

$year = (int)$_GET['y'];

должно сработать.Вводя целое число в целое число, вы удаляете там любые возможности.

f будет немного сложнее.Вы не дали нам представление о том, как называются файлы.Вы захотите добавить проверку соответствия шаблону, чтобы обеспечить поиск только допустимых имен файлов.Например, если все PDF-файлы называются «report_something_0000.pdf», тогда вы захотите проверить, скажем,

$file = null;
if(preg_match('/^report_something_\d{4}\.pdf$/', $_GET['f'])) {
    $file = $_GET['f'];
}

Теперь, когда у нас есть правильное имя файла и правильный годовой каталог,Следующим шагом является . Убедитесь, что файл существует .

$path = 'E:/Omrop/' . $year . '/' . $file;
if(!$file || !file_exists($path) || !is_readable($path)) {
    header('HTTP/1.0 404 File Not Found', true, 404);
    header('Content-type: text/html');
    echo "<h1>404 File Not Found</h1>";
    exit;
}

Если $file не было установлено из-за сбоя сопоставления с шаблоном или если не найден путь к файлу, сценарий отправит сообщение об ошибке.

Я собираюсь предположить , что ваши проблемы с открытием старых PDF-файлов вызваны тем, что файлы не существуют или имеют плохие разрешения.Вы предоставляете Adobe Reader правильные заголовки, а затем никаких данных.

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

Далее, избавьтесь от @ перед readfile.Это подавляет любые реальные ошибки, и вы захотите их увидеть.Поскольку вы, вероятно, не хотите видеть их в выводе, убедитесь, что вместо них настроен журнал ошибок .

Наконец ... как этот код вообще работает? Вы излучаете заголовки в середине HTML! Мало того, вы при этом даете явную длину содержимого.Вы должны получить чертовски много ошибок от этого.Вы уверены, что случайно не скопировали / вставили какой-то код здесь?Может быть, вы забыли раздел в верхней части, где вы звоните ob_start()?Несмотря на это, канаву все до открывающего тега <?php.

...