Joomla система включает множество функций, которые помогают с задачей защиты приложений и расширений построена на этом. Вы всегда должны использовать эти возможности, если это вообще возможно, как они были опробованы и протестированы многие глазах сообщества разработчиков и любые обновления, что может предположительно быть приняты в будущем, будут автоматически доступны при обновлении Joomla применяется. Далее следует описание передового опыта в использовании Joomla API, чтобы убедиться, что ваш расширения максимальной безопасности.
Получение данных из запроса
Все входные происходящих из пользователь должен рассматриваться как потенциально опасен и должен быть очищен до использования. Вам следует всегда использовать Joomla Рамочной JRequest класса для извлечения данных из запроса, а не сырье $ _GET, $ _POST, $ _REQUEST переменных как JRequest методы применяются фильтрации входных данных по умолчанию. JRequest занимается всеми аспектами запросу пользователя таким образом, что не зависит от метода запроса используется. Она также может использоваться для получения данных печенье и даже переменные окружения и сервера. Однако, важно использовать правильную JRequest метод для обеспечения максимальной безопасности. Это очень легко использовать только JRequest:: getVar метод с параметрами по умолчанию и игнорировать тот факт, что во многих случаях можно применить более жесткие требования на ввод данных пользователем.
Это очень важно понимать, что JRequest методы не SQL-Aware и необходима дальнейшая работа для защиты от SQL-инъекций attacks.There нет значения по умолчанию, которые будут возвращены, если по умолчанию не указан в вызове JRequest:: getVar. Если он не указан, и аргумент не в запросе переменной, то он вернется не определено.
Использование JRequest также устраняет необходимость обратить внимание на установки magic_quotes_gpc. JRequest делает правильные вещи, независимо от того, magic_quotes_gpc включена или выключена. См. http://php.net/manual/en/security.magicquotes.php для получения дополнительной информации.
При рассмотрении пользовательского ввода вы должны думать о данных типа вы ожидаете получить и применить самые жесткие формы JRequest, применимой в каждом конкретном случае. В частности, не ленивый подход с использованием JRequest:: получить как это вернет массив, который может содержать записи, которые вы не ожидали, и, хотя каждый из этих записей будет очищена, это часто бывает, что дополнительной фильтрации можно было бы в применении к некоторым отдельным аргументов. Например, получить метод обрабатывает все аргументы как строки, а это может быть возможным ограничить некоторые аргументы, чтобы быть целыми числами.
Первые три параметра каждого из JRequest получить методы те же. Только первый параметр является обязательным. В общем, формат
JRequest::get<type>( <name>, <default>, <data-source> )
где
| <type> |
Тип данных для их загрузки (см. ниже типы). |
| <name> |
имя переменной для его загрузки (например, имя аргумента в URL). |
| <default> |
Значение по умолчанию. |
| <data-source> |
Указывает, где переменная должна быть получен из (см. ниже). |
Следующие значения для <data-source> поддерживаются:
| GET | Данные, представленные в запросе часть URL. |
| POST | Данные, представленные из полей формы. |
| METHOD | Так же, как ни GET или POST в зависимости от того, как был сделан запрос. |
| COOKIE | Данные, представленные в печенье. |
| REQUEST | Все GET, POST и COOKIE данные, вместе взятых. Это по умолчанию. |
| FILES | Информация о закачанных файлов как часть запроса POST. |
| ENV | Переменные среды (платформы). |
| SERVER | Веб переменных сервера (платформы). |
Обратите внимание, что по умолчанию запрос, который включает в себя печенье данных.
В следующих разделах рассмотрим каждый из типов данных более подробно.
Целое число
Следующие будет принимать целое. Целое может включать в себя ведущих знаком минус, но плюс не допускается.
$integer = JRequest::getInt( 'id' );
вернет значение "ID" аргумент от запроса (которая по умолчанию включает в себя все GET, POST и COOKIE данные). Значение по умолчанию равно нулю
$integer = JRequest::getInt( 'myId', 12, 'COOKIE' );
вернет значение "MyID" переменную из печенья, по умолчанию значение 12.
Число с плавающей точкой
Число с плавающей точкой может включать в себя ведущих знаком минус, но не знаком плюс. Если число включает десятичную точку, то должно быть по крайней мере одну цифру до десятичной точки. Например,
$float = JRequest::getFloat( 'price' );
вернет значение аргумента 'цена' из запроса. По умолчанию используется "0,0".
$float = JRequest::getFloat( 'total', 100.00, 'POST' );
будет извлекать значение аргумента "Всего" из запроса POST (но не GET), по умолчанию значение 100,00.
Логическое значение
Любое ненулевое значение рассматривается как истинное; нулю неверно.
$boolean = JRequest::getBool( 'show' );
вернет значение ЛОЖЬ, если значение аргумента "шоу" в запросе равен нулю, или 1 (истина), если аргумент-нибудь еще. Умолчанию является ложным. Обратите внимание, что любая строка аргумента приведет к возвращению значение
True, поэтому вызов выше с URL, содержащие "? Показать = False" на самом деле возвращения правда!
$boolean = JRequest::getBool( 'hide', true, 'GET' );
будет извлекать значение "скрыть" аргумент от GET запрос (но не POST), значение по умолчанию истины.
Word
Слово определяется как строка из букв. Символ подчеркивания разрешен как часть слова.
$word = JRequest::getWord( 'search-word' );
будет извлекать значение аргумента "Поиск-слова" из запроса. По умолчанию используется пустая строка.
$word = JRequest::getWord( 'keyword', '', 'COOKIE' );
будет извлекать значение переменной "Ключевое слово" из печенья, по умолчанию поиск производится пустая строка.
Командная
Команда, как слово, но более широкий диапазон символов не допускается. Разрешенные символы: все буквы, цифры, точки, тире (дефис) и подчеркивания.
$command = JRequest::getCmd( 'option' );
будет извлекать значение "вариант" аргумент от запроса. Значение по умолчанию пустая строка.
$command = JRequest::getCmd( 'controller', 'view', 'POST' );
будет извлекать значение "контроллер" аргумент в пользу запрос POST (но не GET), по умолчанию значение "вид".
String
Строка типа позволяет получить более широкий диапазон входных символов. Он также принимает необязательный четвертый аргумент, указывающий, некоторые дополнительные параметры маски. См. # Параметры фильтра для получения информации о доступных масок.
$string = JRequest::getString( 'description' );
будет извлекать значение "описание" аргумент от запроса. Значение по умолчанию пустая строка. Вход будет иметь пробелы удалены из левого и правого концов и любой HTML-теги будут удалены.
$string = JRequest::getString( 'text', '', 'METHOD', JREQUEST_NOTRIM );
будет извлекать значение "текст" аргумент в пользу запросу .. Значение по умолчанию пустая строка. Начальные и конечные пробелы не будут удалены.
$string = JRequest::getString( 'template', '<html />', 'METHOD', JREQUEST_ALLOWHTML );
будет извлекать значение "Шаблон" аргумент в пользу запросу. Значение по умолчанию '<html />'. Начальные и конечные пробелы будут удалены, но HTML будет разрешено.
Общие и другие типы данных
Если эти методы не отвечают вашим потребностям, есть небольшое число дополнительных типов фильтров, который можно использовать по телефону
JRequest:: getVar метод непосредственно. Синтаксис:
JRequest::getVar( <name>, <default>, <data-source>, <type>, <options> );
где:
| <name> | имя переменной для его загрузки (например, имя аргумента в URL). |
| <default> | Значение по умолчанию. Существует нет значения по умолчанию, которые будут возвращены, если по умолчанию не указан в вызове JRequest:: getVar. Если он не указан, и аргумент не в запросе переменной, то он вернется не определено. |
| <data-source> | Указывает, где переменная должна быть получен из (один из GET, POST, МЕТОД, COOKIE, REQUEST, ENV, SERVER; поумолчанию запросу). |
| <type> | Указывает тип данных ожидалось (см. ниже). |
| <options> | дополнительный бит-поле используется для определения вариантов для некоторых входных фильтров (см. ниже). |
Первые три аргумента же, как и для более конкретных методов, описанных ранее. Только первый аргумент является обязательным.
Допустимых значений <type>, который является независимым от регистра, являются следующие:
| INT, INTEGER | Эквивалент JRequest::getInt. |
| FLOAT, DOUBLE | Эквивалент JRequest::getFloat. |
| BOOL, BOOLEAN | Эквивалент JRequest::getBool. |
| WORD | Эквивалент JRequest::getWord. |
| ALNUM | Разрешить только буквенно-цифровых символов (a-z, A-Z, 0-9). |
| CMD | Эквивалент JRequest::getCmd. |
| BASE64 | Разрешить только те символы, которые могут присутствовать в 64-разрядной кодировки (т.е. a-z, A-Z, 0-9, /, + and =). |
| STRING | Эквивалент JRequest::getString. |
| ARRAY | Источник не фильтруется, но является приведение к массиву типа. |
| PATH | Действительный путь регулярное выражение, которое отфильтровывает распространенных атак. Например, любой путь, начиная с "/" вернется пустая строка. Simliarly, любой путь, содержащий "/./" or "/../" вернется пустая строка. Точки в именах файлов все в порядке, хотя. |
| USERNAME | Удаляет символы управления (0x00 - 0x1F), 0x7F, <, >, ", ', % and &. |
Filter options
Допустимых значений <options> выглядит следующим образом (ни одна из этих применяются по умолчанию):
| JREQUEST_NOTRIM | Не удаляет пробелы из начала и концы строк. |
| JREQUEST_ALLOWRAW | не делает никакой фильтрации на всех. Используйте с крайней осторожностью. |
| JREQUEST_ALLOWHTML | Не удаляет из строки HTML входов. |
Маски могут быть объединены логически OR'ing них. Если нет фильтра опции не указаны, то по умолчанию, пробел обрезается и HTML будет удален.
Файл добавления
Веб-серверы уже есть немало безопасности вокруг Загрузка файлов на сервер, но он по-прежнему необходимо принять дополнительные меры для обеспечения того, чтобы имена файлов и пути их злоупотребления. Упрощенном виде в котором содержится просьба файл для загрузки выглядит следующим образом:
<form action="index.php?option=com_mycomponent/form_handler.php" method="post" enctype="multipart/form-data">
<input type="file" name="Filedata" />
<input type="submit" />
</form>
При нажатии кнопки "Отправить", браузер будет загружать файл в запросе POST, передачей управления Joomla, который будет вызывать "components/com_mycomponent/form_handler.php". Это будет включать в себя код, подобный следующему. Переменная $ somepath должен быть установлен в какой-то путь, где веб-сервер имеет разрешение на создание файлов.
// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die( 'Restricted access' );
// Get the file data array from the request.
$file = JRequest::getVar( 'Filedata', '', 'files', 'array' );
// Make the file name safe.
jimport('joomla.filesystem.file');
$file['name'] = JFile::makeSafe($file['name']);
// Move the uploaded file into a permanent location.
if (isset( $file['name'] )) {
// Make sure that the full file path is safe.
$filepath = JPath::clean( $somepath.'/'.strtolower( $file['name'] ) );
// Move the uploaded file.
JFile::upload( $file['tmp_name'], $filepath );
Сохранение переменных запроса в состоянии пользователя
Поскольку установка переменной состояния пользователя из переменной в запросе, является такой распространенной операцией, есть метод API, чтобы сделать задачу. Это, как правило, безопасны в использовании, поскольку она вызывает [JRequest / getVar | JRequest::
getVar]] для получения вклада запрос, но помните, что ни один из фильтрации входных звонков будет защищать от попытки SQL инъекции.
$app =& JFactory::getApplication();
$app->getUserStateFromRequest( <key>, <name>, <default>, <type> );
где
| <key> | имя переменной в состоянии пользователя. |
| <name> | имя запроса переменной (такой же как первый аргумент JRequest:: getVar вызова). |
| <default> | значение по умолчанию присваивается переменной состояния пользователя, если запрос переменная отсутствует. По умолчанию NULL. |
| <type> | тип переменной ожидается (то же, четвертый аргумент JRequest:: getVar вызова). |
Например, получение целой переменной называется "ID" из запроса по умолчанию значение 0, то сохранение его в переменной сессии называется "MyID" может быть сделано следующим образом:
$app =& JFactory::getApplication();
$app->getUserStateFromRequest( 'myid', 'id, 0, 'int' );
а что-то вроде этого:
$app =& JFactory::getApplication();
$app->setUserState( 'myid', JRequest::getInt( 'id', 0 ) );
Построение SQL запросов
Один из наиболее распространенных форм атак на веб-приложений SQL-инъекции, где целью злоумышленника является изменение запроса к базе данных, используя плохо фильтруется входных переменных. Потребители инъекционных изменение инструкции SQL в базе данных может привести к повреждению данных или раскрывать конфиденциальную информацию. Важно обеспечить, чтобы, когда SQL заявления строятся, они правильно избежал и цитирует так, что плохо входных данных не может привести к плохим заявление SQL. Вы не можете полагаться на JRequest методы для этого, поскольку они не SQL-Aware.
С базой данных MySQL, числовых полей не должно быть заключено в кавычки, поэтому важно, чтобы они были приведение вместо. Неспособность сделать это будет оставить свой код уязвимым для злоумышленника вставки строку, содержащую данные SQL.
В зависимости от типа, числовых типов поданы так:
// For SQL data types: INT, INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT, YEAR
$query = 'SELECT * FROM #__table WHERE `id`=' . (int) $id;
// For SQL data types: FLOAT, DOUBLE
$query = 'SELECT * FROM #__table WHERE `id`=' . (float) $id;
В приведенных ниже примерах предполагается, что $ БД экземпляр объекта базы данных Joomla. Это всегда можно получить из JFactory использованием
$db =& JFactory::getDBO();
Строки должны быть всегда бежал перед использованием в заявлении SQL. На самом деле это очень просто, как [[JDatabase-> quote]] метод побег все для вас. Вы также можете использовать [[JDatabase-> getEscaped]] метод непосредственно. Следующие утверждения эквивалентны:
$query = 'SELECT * FROM #__table WHERE `field` = ' . $db->quote( $db->getEscaped( $field ), false );
$query = 'SELECT * FROM #__table WHERE `field` = ' . $db->quote( $field );
Особое внимание должно быть уделено НРАВИТСЯ положения, которые содержат% подстановочный знак, как это требует специальной побега, чтобы избежать возможных атак отказа в обслуживании. НРАВИТСЯ положения могут быть обработаны следующим образом:
// Construct the search term by escaping the user-supplied string and, if required, adding the % wildcard characters manually.
$search = '%' . $db->getEscaped( $search, true ) . '%' );
// Construct the SQL query, being careful to suppress the default behaviour of Quote so as to prevent double-escaping.
$query = 'SELECT * FROM #__table WHERE `field` LIKE ' . $db->quote( $search, false );
Если данные должны быть введены в столбец DateTime то вы можете использовать
Joomla API для обеспечения допустимого формата даты:
$date =& JFactory::getDate( $mydate );
$query = 'UPDATE #__table SET `date` = ' . $db->quote( $date->toMySQL(), false );
Обратите внимание, что необходимо, чтобы подавить базы данных избежать законной даты могут содержать символы, которые не должны быть экранированы.
В сравнительно редких случаях, когда имя поля переменных, которые также должны быть указаны использованием вызовов API:
$query = 'SELECT * FROM #__table WHERE ' . $db->NameQuote( $field-name ) . '=' . $db->quote( $field-value );
Защита форм
Помимо очистки входных переменных, как описано выше, вы можете также осуществлять простую технику, которая делает его более трудным для кросс-сайт атаки подделке запросов (CSRF) для достижения успеха. Это включает в себя добавление случайно сгенерированный уникальный ключ к форме, которая сравнивается с копией маркер состоявшейся в сессии пользователя. Установив, что
представленный знак соответствует той, которая содержится в хранимой сессии, можно связать оказанных форму запроса переменных представлены.
В POST формы необходимо добавить скрытый маркер поле с помощью:
echo JHTML::_( 'form.token' );
Это выводит маркер как скрытое поле формы вида:
<input type="hidden" name="8cb24ae69ffd7828ccecbcf06056e6fc" value="1" />
и помещает копию маркера в сессии пользователя, для последующего контроля.
Если вам нужно добавить маркер для URL, а не формы, то вы можете использовать что-то вроде этого:
echo JRoute::_( 'index.php?option=com_mycomponent&' . JUtility::getToken() . '=1' );
В наиболее распространенный сценарий, вам нужно будет проверить маркер следующей POST к форме обработчик. Это может быть сделано путем добавления этой строки кода, чтобы обработчик формы:
JRequest::checkToken() or die( JText::_( 'Invalid Token' ) );
Если вам необходимо передать маркер в GET запросе, то вы можете проверить это следующим образом:
JRequest::checkToken( 'get' ) or die( JText::_( 'Invalid Token' ) );
В обоих случаях код умрет, если маркер исключить из запроса, или представленные маркер не соответствует маркер сеанса. Если маркер правильно, но истек, то JRequest:: checkToken будет автоматически перенаправлять на первой странице сайта.
Очистка путей файловой системы
Если есть возможность, что файловая система путь может быть построен с использованием данных, который проистекает из пользовательского ввода, то путь должен быть очищены и проверены перед использованием. Это может быть сделано просто так:
JPath::check( $path );
Это вызовет ошибку и прекратить Joomla, если путь содержит ".." или приводит к местонахождение за пределами корневой директории Joomla. Если вы хотите иметь дело с ошибкой себе, не закрывая приложения, то вы можете использовать такой код:
$path = JPath::clean( $path );
if (strpos( $path, JPath::clean( JPATH_ROOT ) ) !== 0) {
// Handle the error here.
}
JPath: чистый метод может быть использован в коде тоже. Она просто удаляет начальные и конечные пробелы и заменить двойные слэши и
обратную косую черту со стандартным разделителем каталогов.
Очистка имен файловой системы файл
Как и в файловой системе путей, если есть возможность того, что имя файла может быть построена с помощью пользовательских данных возникла, то имя файла должно быть очищены и проверены перед использованием. Это можно сделать следующим образом:
jimport('joomla.filesystem.file');
$clean = JFile::makeSafe( $unclean );
Этот метод удаляет последовательности из двух или более "." символов и любой символ, не буквенные и числовые или точка, тире или символа подчеркивания. Если есть ведущей точки то, что удаляется слишком.
