Архив января 2008

Проверка имени файла на безопасность

Понедельник, 28 января, 2008

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

Таковыми в частности являются:

/ или \ в начале имени может позволить обратиться к произвольному месту в файловой системе (если не указан текущий путь, это позволит открывать файлы в любом месте файловой системы, а не только ниже текущего каталога);

.. (две точки) — позволит подняться в каталог более высокого уровня и открыть файл там;

~ (тильда) — если интерпретатор выполняется от реального пользователя, а не от nobody (т.е. PHP запускается как CGI), позволяет открыть файл в его родительском каталоге;

` (обратный апостроф) — в некоторых ситуациях может позволить выполнить внешнюю команду на сервере;

://(часть, отделяющая протокол в URL от доменного имени) — при разрешенном подключении внешних файлов позволит загрузить и выполнить произвольный PHP-код.

Кроме того, ряд символов может привести к созданию нечитаемых/неудаляемых файлов, вызывать ошибку при записи или ошибку в HTML при формировании ссылки, поэтому их тоже желательно фильтровать. К таким символам относятся: двоеточие (:), точка с запятой (;), запятая (,), кавычки (”), апостроф (’), амперсанд (&), символы больше и меньше (<>).

В результате получаем следющую процедуру проверки:

function check_name( $filename) {
    $result=(substr($filename,0,1)!='/' && substr($filename,0,1)!='\\');
    if ($result) {
      $test=array('..','://','~','`','\'','"',':',';',',','&','>','<');
      for ($i=0, $count=count($test); $i<$count && $result; $i++) $result=(strpos($filename,$test[$i])===false);
    }
    return $result;
}

Кроме того, при загрузке файла имеет смысл сохранять его с таким именем, чтобы пользователь не мог его угадать (лучше всего для этой цели подходит MD5-хеш от имени + размера + времени загрузки + случайного значения), и не давать возможности узнать имя файла из URL ссылки для его скачивания/просмотра (т.е. если данные о загруженном файле хранятся в таблице БД, то скрипту для скачивания передавать номер этого файла в таблице, а не его имя).

О корректном использовании flock

Среда, 23 января, 2008

Как известно, flock используется для блокировки файлов с целью предотвращения одновременного доступа к ним двух скриптов. Но следует учитывать, что простой вызов flock($fh,$mode) не на всех платформах приводит к ожиданию блокировки файла в том случае, если ее не удалось выполнить сразу. Поэтому более правильно вызывать эту функцию следующим образом:

$fh=fopen('filename','r');
if (!$fh) {echo 'Error!'; }
else {while (!flock($fh,$mode)) sleep(1);
// обработка файла
fclose($fh);
}

В этом случае при неудачной попытке заблокировать файл скрипт переходит в sleep-состояние на секунду, после чего повторяет попытку. В PHP 5 можно вместо функции sleep использовать usleep, для которой время задается в микросекундах (при этом желательно добавить в интервал ожидания некоторую случайную составляющую, чтобы избежать повторения попыток блокировки разными скриптами в одно и то же время).

Виртуальная клавиатура

Среда, 23 января, 2008

Неплохая реализация виртуальной клавиатуры доступна по адресу: http://www.greywyvern.com/code/js/keyboard.html.

Среди ее достоинств можно отметить поддержку множества раскладок,  простую интеграцию в Web-страницу и полностью задаваемый внешний вид через CSS.

Отображение блока в нижней части страницы

Пятница, 18 января, 2008

Часто требуется сделать так, чтобы “подвал” страницы отображался в самом ее низу даже в тех случаях, когда на странице мало контента. Реализуется это следующим образом: в CSS тегам body и html присваивается высота 100%.

Далее основной контент берется в один блок div (назовем его content), “подвал” — в другой (назовем его footer). Блоку content присваивается минимальная высота (min-height) 100%, для footerа высота задается явно. Нижнее поле блока content задается равным высоте footerа, а для самого footerа верхнее поле указывается в 2 раза больше, чем его высота.

В результате получаем следующий код:

<html><head><style type="text/css"><!--
html { height: 100%; }
body { height: 100%}
#content { min-height: 100%; margin-bottom: 50px }
* html #content { height: 100% } /* Это для Internet Explorer, который не воспринимает min-height */
footer { height: 50px; position: relative; margin-top: -100px; }
--></style></head>
<body>
<div id="content">
Здесь находится основное содержимое
</div>
<div id="footer">
А это подвал сайта
</div>
</body></html>

Советы: 1) для того, чтобы подвал масштабировался при изменении размера шрифта в броузере, поля и высоту имеет смысл задавать не в пикселях, а в относительных единицах (em);
2) нижнее поле у body должно быть равно нулю (типичная ошибка — использование конструкций вида body { 5px 10px}, которые добавляют не только верхнее, но и нижнее поле).

Тег OBJECT

Среда, 16 января, 2008

Тег Object используется, в основном, для вставки Java-апплетов и Flash-роликов. Но при этом при вставке Flash-роликов совместно с ним часто используется устаревший тег Embed, что вызывает негативную реакцию валидаторов. К сожалению, некоторые даже современные броузеры, в частности, Firefox, без тега Embed не отображают Flash-ролик. Но тем не менее, отобразить ролик без Embed можно и в Firefox, если учитывать следующие его особенности:

1) для ролика должна быть точно указана высота и ширина в пикселях
2) для ролика не должен быть указан параметр classid
3) адрес ролика должен быть указан в параметре data тега Object (при этом вложенный тег <param name=”movie” value=”flash.swf”> должен все равно присутствовать, т.к. он используется MSIE).

Кроме того, в теге Object можно разместить вложенный рисунок или текст, который будет показываться в том случае, если у пользователя не установлен plugin для отображения объекта.

Таким образом, чтобы тег Object работал во всех современных броузерах и был валидным с точки зрения W3C, он должен иметь примерно такой вид:

<object data="файл.swf" type="application/x-shockwave-flash" width="ширина" height="высота">
<param name="allowScriptAccess" value="sameDomain">
<param name="movie" value="файл.swf">
<param name="quality" value="high">
<param name="bgcolor" value="#ffffff">
<img src="файл.png" alt="Включите графику или установите Flash-плеер" height="высота" width="ширина">
</object>

jQuery — JavaScript-библиотека для работы с DOM и AJAX

Суббота, 12 января, 2008

jQuery — это мощная библиотека для программирования на JavaScript. Ее основной особенностью является возможность обращаться к элементам HTML-документа и результатам AJAX-запроса с помощью выражений XPath или шаблонов CSS, а также удобное преобразование HTML-кода в элемент. Все это делается одним вызовом “магической” функции $ (она же jQuery):

$("<div>Тест</div>").appendTo("body"); // динамическое создание элемента из HTML-кода и добавление в документ
$("ul/li:visible") // выбор всех элементов списков, для которых включена видимость

Кроме того, в библиотеке есть функции, котрые значительно упрощают работу с AJAX (фактически, все сводится к вызову функций $.post, $.get с параметрами url, params, и callback и написаню, при необходимости, обработчика, которому сразу же передается XML-результат вызова), а также предоставляют возможность получать в качестве ответа HTML-код (AHAH, функция load) или блок JavaScript-кода (AJAJ, функция getJSON). Также в библиотеке есть функция getScript, которая подгружает и выполняет JavaScript с заданным URL.

Важно отметить достаточно малый объем библиотеки: в сжатом GZIP виде она занимает всего лишь 14 Kb, в упакованном — 26 Kb.
Официальный сайт jQuery: http://jquery.com/

Статья на русском языке об основах работы с jQuery: http://rsdn.ru/article/inet/jQuery.xml

Панели управления сервером

Пятница, 11 января, 2008

Несколько open-source панелей управления сервером/хостингом:

ISPConfig (http://ispconfig.org/) — работает с несколькими дистрибутивами Linux.

Web-CP (http://www.web-cp.net/) — работает как с Linux, так и с FreeBSD.

RavenCore (http://www.ravencore.com/) — также работает с некоторыми дистрибутивами Linux.

Обзор хостингов

Понедельник, 7 января, 2008

На сайте HOSTOBZOR.RU представлен весьма неплохой выбор всех видов хостинга (виртуальный хостинг, VDS, Dedicated server, реселлинг, парковка). Имеется возможность выбора тарифных планов, трассировки серверов из нескольких географических мест, просмотр отзывов.

Простой перенос данных из форм в несколько таблиц

Понедельник, 7 января, 2008

Часто бывают ситуации, когда требуется данные, которые пользователь вводит в форму, разместить в нескольких разных таблицах базы данных. Наиболее простым и красивым решением в таком случае будет именовать поля в форме следующим образом: имя_таблицы[имя_столбца]. В этом случае PHP при получении данных создаст в массиве $_POST (или $_GET) подмассивы, в каждом из которых будут только те элементы, которые относятся к одной и той же таблице. Остается только написать функцию, которая будет сохранять все поля массива в таблицу.

Пример такой ситуации: форма содержит поля topic['title'], topic['descr'], post['text'], post['date'], download[url], download[homepage].

В этом случае обрабатывать ее можно будет примерно таким образом:

$topic_id=$db->save('topic',$_POST['topic']);
$post_id=$db->save('post',$_POST['post']);
$_POST['download']['id']=$topic_id; // таблица download привязывается к таблице Topic по id
$db->save('download',$_POST['download']);

Совет: при необходимости можно организовать цикл по массиву таблиц вместо того, чтобы вызывать функцию для каждой таблицы поштучно. Но при этом список таблиц должен все равно указываться явно (т.е. нельзя проходить циклом по $_POST и пытаться сохранить все, что является подмассивом, хотя в первый момент такое решение кажется привлекательным), так как в противном случае пользователь может изменить форму и внести данные в те таблицы, в которые делать этого не предполагалось (например, в таблицу прав доступа).

Сайт для генерации предварительного просмотра сайтов

Воскресенье, 6 января, 2008

THUMBSHOTS.ORG — сайт для генерации картинок предварительного просмотра (previews, site thumbnails) сайтов с возможностью встраивания таких картинок в скрипты.


Rambler's Top100