Решено! Как обезопасить данные полученные через com_ajax.

Тема в разделе "Вопросы безопасности", создана пользователем OlegK, 21.03.2018.

  1. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Разработчики Джумла предлагают пропускать массив без фильтрации или прописывать для каждого элемента массива фильтр.
    https://github.com/joomla-framework/input
    Код (CODE):
    1. $fooValues = $jinput->getArray(array(
    2.     'var1' => 'int',
    3.     'var2' => 'float',
    4.     'var3' => 'word'
    5. ));

    https://docs.joomla.org/Retrieving_request_data_using_JInput
    Мое решение
    Код (CODE):
    1. $arfields =  filter_input(INPUT_POST, 'arfields', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY);
    Где arfields это массив, отправленный с помощью Аякс
    Код (CODE):
    1. var fields = jQuery(":checkbox:checked").serializeArray();
    2.     var request = {
    3.                     'option' : 'com_ajax',
    4.                     'module' : 'nwella',
    5.                     'format' : 'json',
    6.                      'arfields'   : fields,
    7.                 };
    8. jQuery.ajax({
    9.             type   : 'POST',
    10.             data   : request})
     
  2.  
  3. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Не то чтобы дынное решение не верно просто зачем отрезать приличный кусок фильтрации и валидации ради сокращения кода на пару строк.

    Если говорить о формах. То можно и нужно просто юзать родной Jform ->validate для валидации и фильтров. Кроме того в сам Jinput встроена фильтрация, куда более широкая чем родной filter_input. Ну а если предавать всего пять полей, то и нет смысла передавать их массивом
    Я сейчас переписываю свой модуль JForm так что скину просто кусок кода.

    Код (PHP):
    1. /**
    2. * Method to validate the form data.
    3. *
    4. * @param   \JForm $form The form to validate against.
    5. * @param   array  $data The data to validate.
    6. *
    7. * @return  array|boolean  Array of filtered data if valid, false otherwise.
    8. *
    9. * @see     \JFormRule
    10. * @see     \JFilterInput
    11. * @since   1.6
    12. */
    13. public static function validate($form, $data)
    14. {
    15.    // Include the plugins for the delete events.
    16.    PluginHelper::importPlugin('content');
    17.  
    18.    $dispatcher = \JEventDispatcher::getInstance();
    19.    $dispatcher->trigger('onUserBeforeDataValidation', array($form, &$data));
    20.  
    21.    // Filter and validate the form data.
    22.    $data   = $form->filter($data);
    23.    $return = $form->validate($data);
    24.  
    25.    // Check for an error.
    26.    if ($return instanceof \Exception)
    27.    {
    28.       throw new Exception($return->getMessage(), 404);
    29.  
    30.       return false;
    31.    }
    32.  
    33.    // Check the validation results.
    34.    if ($return === false)
    35.    {
    36.       // Get the validation messages from the form.
    37.       foreach ($form->getErrors() as $error)
    38.       {
    39.          throw new Exception($error->getMessage(), 404);
    40.  
    41.       }
    42.  
    43.       return false;
    44.    }
    45.  
    46.    return $data;
    47. }

    Сам модуль пока что без валидации https://github.com/Septdir/mod_jform
    Ну и другой модуль но сделанный по томуже принципу (собственно когда его Артем писал я и придумал юзать JFrom в модулей)
    https://github.com/ArtPavluk/mod_artcallme

    P.S в АJAX запросе ошибка, не передан пункт меню => не будет работать на Joomla < 3.8.7
     
  4. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Ну откуда пару строк. И я же привел цитату- нет фильтрации, если не указать явно фильтр для каждого ключа массива. А если неизвестно сколько придет элементов массива и делать проверку на наличие и не empty .
    см выше . И полей не 5, и массив не один приходит с формы .
     
  5. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Циклом, да и к тому же всегда известно сколько и в каком виде приходит. Если к примеру делать модуль конструктор, то поля все равно получать из настроек модуля. Варианта два
    1. Форма фиксированная => я изначально знаю какие поля приходят и что там должно быть.
    2. Форма конструктор => все это есть в настройках модуля.

    И проверка на пустоту и на isset решается через $app->input то бишь, к примеру если это не конструктор можно просто объявить массив и получать поля по одному. к примеру так
    Код (PHP):
    1. $app               = \Joomla\CMS\Factory::getApplication();
    2. $fields            = array();
    3. $fields['filed_1'] = 'raw';
    4. $fields['filed_2'] = 'int';
    5. $fields['filed_3'] = 'array';
    6.  
    7. $result = array();
    8. foreach ($fields as $name => $filter)
    9. {
    10.    if ($value = $app->input->get($name, false, $filter))
    11.    {
    12.       $result[$name] = $value;
    13.    }
    14. }

    Ну а если форма большая или это конструктор, то удобнее и лучше юзать JFORM. Тут и вывод на layouts и валидация, капча без велосипедов и с отправкой проблем нет. Вообще когда надо сделать любые формы в joomla JForm рулит, главное лишь его освоить.

    Примерно такая логика. ИМХО какой смысл использовать движок, если ты не юзаешь его предустановленные функции.

    Ну а так в кодинге если решение работает, то оно не может быть не правильным, оно может быть не оптимальным, а в вопросе оптимальности, сколько людей столько и мнений.
     
    Последнее редактирование: 21.03.2018
  6. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Да просто я уже умею выбирать оптимальное решение , а не просто копиастить код разработчиков Джумла. Ну и com_ajax я использую,
    И вообще я нашел решение, поделился, а ты тут холивар устроил . Я ж не заставляю тебя использовать мое решение.
    А ты учишь меня кодить, уже в который раз.
     
  7. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Я не устроил холивал, а высказал свое мнение, если тут так не принято, а принято что любое предложение решение являеться абсолютно верным, то прошу прощения. Больше так делать не буду.

    И это не просто решение разработчиков. Это простой код валидации с использованием JFROM.
    Это и называется использовать возможности движка, хотя точнее сказать возможности фреймворка.

    Насчет оптимальности предложного тобой решения я свое мнение высказал . Могу долго писать почему оно не оптимально.
    Вот простой например
    Как при таком решении использовать фильтр HTML в зависимости от настроек joomla?
    Как использовать валидацию капчи в зависимости от плагина
    Как использовать родную custom validation rule, ну например проверить уникальность value
    И т.д

    Если это все писать получиться тот же JFROM только в профиль причем где-то с 1/4, если не меньше функционала. Так к чему же изобретать велосипед заново?
    Собственно тоже относиться и к JInput. Поэтому более короткий код далеко всегда значит что он оптимальнее. Если краткость кода ставиться на первое место вернее будет написать свое ядро с минимальным набором функций и проверок.

    Все приведенные мной примеры именно из модулей с использованием com_ajax.

    В данный момент com_ajax проверят наличие модуля используя функцию JModuleHelper::getModule, которая в свою очередь проверят привязку модуля к пунктам меню, права доступа, опубликованость и т.д исправлено это будет только в 3.8.7
    https://github.com/joomla/joomla-cms/pull/19818

    Кстати если это форма то все данные можно просто передать в action или же сделать скрытыми полями.
    Получиться примерно такой короткий код
    Код (javascript):
    1. $.ajax({
    2.    type: 'POST',
    3.    dataType: 'json',
    4.    url: $(this).attr('action'),
    5.    data: $(this).serializeArray(),
    6.    success: function (response) {
    7.       if (response.success == false) {
    8.  
    9.       }
    10.       else {}
    11.    }
    12. });

     
    Последнее редактирование: 21.03.2018
  8. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Я написал всего 1 строку кода. Ты тут выложил целые простыни. У меня нет времени на вникание в суть твоих изысков.
    Но я б еще понимал холивар с кодером С++, про неправильный парсер движка . Но ты стараешься доказать неэффектиновсть нативного функционала движка ПХП, который используется в том же framework Joomla!.
     
  9. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Кстати можно и в одну строку получить все =)
    Код (PHP):
    1. $app->input->post->get('arfields', array(), 'array');

    Вернет весь массив arfields =)

    А метод getArray() предназначен именно для того чтобы каждому отдельному значению в массиве задать свой фильтр, я думал мы об этом спорим если честно.

    На сим откланяюсь ибо не вижу смысла спорить с таким крутым кодером =)

    P.S вообще-то наоборот фрейморк используется в движке =) И кстати я тоже пишу на C++ но это не доставляет мне удовольствие.
     
    Последнее редактирование: 21.03.2018
  10. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    А $app откуда ?
    Фильтрация в твоей одной строке где ? + я и здесь могу еще укоротить. Я же дал ссылки на JInput и использовал этот метод получения на этапе разработки. Но ты читаешь только себя.
    Код (CODE):
    1. $app->input-->get('arfields', array(), 'array');

    Ты задай себе вопрос- зачем я открыл тему и написал решение. Сам и отвечу, чтоб было понятнее читающим тему- да потому что гугл не дал ответа как обезопасить/отфильтровать массив в com_ajax . А поскольку мое хобби кодить плагины, модули используя Аякс jquery, эта тема и мне подскажет всегда решение .
     
  11. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Код (PHP):
    1. $app = \Joomla\CMS\Factory::getApplication();

    Ну во первых тут ошибка -->, во вторых у меня было получение только post специально.

    Фильтр 'array'
    В остальное уже фильтруй как нужно.
    В твоем варианте кода ты снес все кавычки, декодировал спец символы и снес тэги. А если мне нужны тэги, причем только разрешенные?
    Если предлагать решение оно должно быть универсальным. Если предлагать решение для движка то оно должно использовать движок а не на оборот.
    Если же ты считаешь что в движке не оптимальное решение измени работу движка и если твое решение сочтут верным то оно будет включено в него.

    Мне гугл отдал аж два решения =)
    https://docs.joomla.org/Retrieving_request_data_using_JInput
    https://api.joomla.org/cms-3/classes/Joomla.CMS.Form.Form.html#method_validate
    Хотя второе уже дал не гугл а опыт.

    Мое хобби писать любые расширения для joomla, причем зачастую огромные компоненты или целые паки.
    Как к примеру вот такой набор полей тут не мало использования com_ajax с различными валидациями https://github.com/Nerudas/pkg_fieldtypes
    Хотя это уже давно перестало быть хобби и стало работой =)

    P.S писать модули с com_ajax и передавать Itemid ?

    А еще совет чужое мнение стоит учитывать а не воспринимать в штыки считая что ты всегда прав.
     
  12. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Вот мой промежуточный рабочий код .
    Код (CODE):
    1. $jinput = JFactory::getApplication()->input;
    2. $arfields = $jinput->get('arfields', array(),'array');
     
    Alekxandr нравится это.
  13. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Ну да, только я бы все таки получал именно post отдельно. тем самым закрывшись от особо умных товарщий которые лезут в com_ajax прямо запросом с get параметрами.
    Ну и еще я обычно делаю переменную именно для \Joomla\CMS\Factory::getApplication(); ибо потом часто нужны и другие методы.
    Но многое зависит от когда что за модуль.

    Лично я считаю так.
    Если мы говорим о формах то всегда удобнее юзать Jfrom, а если юзать Jform так почему бы просто не написать один модуль и просто выбирать в настройках разные xml файлы? И в итоге получаем один модуль почти на все случаи жизни.
    Вот собственно добавил валидацию
    https://github.com/Septdir/mod_jform/blob/master/helper.php

    P.S была опечатка два тире.
     
    Последнее редактирование: 21.03.2018
  14. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Это ты пишешь о формах, а я написал про безопасность получения данных. И в моем модуле тега <form> нет .
    В GET массив не встречал.
     
  15. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    ну вот пример
    Код (PHP):
    1. arfields[field1]=привет все фильтры так работают


    Так и я о безопасности. при валидации jform мало того, что проверяется required так же применяется и InputFilter и FormRule в включая совсем кастомные. вроде разрешенных html тэгов путей и т.д а не просто объявить что это должен быть массив. убрать тэги, закодировать спец символы

    Собственно этот механизм используется в компонентах. Поэтому если com_ajax использовать для работы с формами. к примеру формы обратной связи это наиболее верных подход, создал xml и радуешься жизни.

    Если же передавать в com_ajax просто значения ну штучек 5, то лучше отправлять и получать их по одному, а не передавать массивом (несколько строк на js и готово)

    Если же так хочется предавать массив то и фильтровать надо по каждому значению ибо
    Где-то надо убрать html, где-то он нужен.
    Где-то надо получать int
    Где-то нужен проверять email
    Где-то path
    Где-то так вообще надо получить raw и писать проверку самому.
    ну и т.д фильтров очень много.

    И в этом случае Безопаснее и Надежнее будет использовать метод getArray и прописать что нужно(это всего лишь маленький массив), а не просто глобально применить FILTER_SANITIZE_STRING.
    Поэтому предложенное тобой решение менее безопасно, надежно и оптимально, пусть оно и занимает меньше строк. И поверь ни один разработчик, ну кроме индусов, не будет писать лишние строки когда без нужды.
     
    Последнее редактирование: 21.03.2018
  16. OlegK
    Offline

    OlegK Russian Joomla! Team Команда форума ⇒ Профи ⇐

    Регистрация:
    17.01.2011
    Сообщения:
    7 813
    Симпатии:
    771
    Пол:
    Мужской
    Твою энергию бы в мирных целях(с)
     
  17. Septdir
    Offline

    Septdir Пользователь => Cпециалист <=

    Регистрация:
    27.11.2017
    Сообщения:
    172
    Симпатии:
    16
    Пол:
    Мужской
    Ну пока мы спорили, я успел не мало всего продумать и воплотить в коде.

    Мирные цели хм, я не мало делаю в мирных целях взять хотя бы мой GitHub

    Мой профиль - это различные разработки и наработки которые я использую сам. От темы для Firefox и полезных файлов для PHPStom до сервера обновлений расширений Joomla! и других полезных скриптов

    JoomlaZen - Расширения для Joomla! рассчитанные на широкую аудиторию, то бишь поставил и все работает.

    Nerudas - Это расширения заточенные под один конкретный сайт, однако знающий человек всегда может найти там интересные и нужные решения. Будь то поле ajax загрузкой изображений или личный кабинет сделанный на расширенном com_users(с входом по номеру телефона, email, или через соц. сети) или доска объявлений, где заместо стандартных категорий используются наборы тэгов.

    Помимо этого всего еще делаю различные PR в том числе и для Joomla!.

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

    Так что наш маленький спор меня ни чуть не отвлек от насущных дел.
     
    Последнее редактирование: 22.03.2018

Поделиться этой страницей

Загрузка...