Получить код ошибки laravel

Содержание

Исключения Laravel: ловим, обрабатываем и создаем собственные

Laravel Exceptions

Обычно веб-разработчики не следят за ошибками. Если что-то идет не так, то мы частенько видим дефолтный текст ошибки Laravel: «Whoops, something went wrong» или, что еще хуже, код исключения, который посетителю совсем ни к чему. Поэтому я решил написать пошаговую статью о том, как элегантно обрабатывать ошибки и показывать посетителю правильную информацию о произошедшем.

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

Подготовка: Задача поиска пользователя

Итак, у нас есть очень простой пример — форма для поиска пользователя по его идентификатору.

У нас есть два маршрута:

И контроллер с двумя методами:

В файле resources/views/users/index. blade. php находится сама форма:

Если мы ищем существующего пользователя и он найден, мы видим такой результат:

Всё это находится в resources/views/users/search. blade. php:

Но это в идеальном случае, а что, если пользователь не найден?

Обработка исключений

Давайте вернемся в реальный мир. Мы не проверяем существование пользователя, в контроллере мы только делаем:

И, если пользователь не найден, то получим это:

Или, понятное дело, мы можем задать APP_DEBUG=false в файле .env, и тогда браузер просто покажет пустую страницу с «Whoops, looks like something went wrong». Но для нашего посетителя все это совершенно бесполезно.

Еще одно быстрое исправление, которое мы можем сделать, это использовать User::findOrFail() вместо просто find() — тогда, если пользователь не найден, Laravel покажет страницу 404 с текстом «Sorry, the page you are looking for could not be found». Но это дефолтная страница ошибки для всего сайта. Для посетителя она, опять таки, бесполезна.

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

Нам нужно знать тип исключения и имя класса, которое оно будет возвращать. В случае с findOrFail() будет выдано Eloquent исключение ModelNotFoundException, поэтому нам нужно сделать так:

Теперь давайте покажем ошибку в Blade:

Результат:

Отлично, мы отобразили ошибку! Но это еще не идеал, верно? Вместо $exception->getMessage() нам нужно показать наше собственное сообщение:

Финальный вариант!

Перемещаем обработку ошибок в Сервис

На данный момент мы взяли очень простой пример одного действия в контроллере — поиск пользователя. В реальном приложении все гораздо сложнее — обычно контроллер вызывает какой-нибудь внешний сервис или метод пакета, которые могут завершиться с какими-угодно ошибками.

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

Давайте переместим нашу логику в app/Services/UserService. php:

А в контроллере нам нужно вызвать этот сервис. Для начала мы внедрим его в метод __construct():

Если вы не знакомы с внедрением зависимостей и как работает контейнер Laravel IOC, то вот официальная документация.

А вот так теперь выглядит наш метод search():

Обратите внимание, мы снова можем использовать $exception->getMessage(), вся проверка ошибок и логика сообщений происходит внутри службы. Мы удалили это из контроллера, он не должен заниматься этим.

Следующий Шаг: Создание собственного класса исключений

Последняя глава этой статьи посвящена улучшению архитектуры. Это когда ваш сервис генерирует свое собственное исключение, связанное с этой конкретной ошибкой, и, в зависимости от ошибки, может быть несколько классов исключений. Хорошим примером такой архитектуры является библиотека Stripe, ее использование выглядит так:

Итак, как мы можем создать наш собственный класс исключений? Очень просто — с помощью команды Artisan:

Сгенерируется app/Exceptions/UserNotFoundException. php:

Здесь же ничего нет, верно? Давайте заполним наше исключение логикой.
В этом классе может быть два метода:

Итак, для этого примера мы cделаем метод report():

А вот так мы вызываем это исключение из контроллера:

Итак, это всё, что я хотел рассказать вам об обработке исключений и использовании Сервисов.

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

Подробнее об исключениях и обработке ошибок: официальная документация Laravel.

Распространенные ошибки безопасности в приложениях Laravel

В большинстве случаев уязвимости безопасности возникают только из-за недостаточной осведомленности, а не из-за халатности. Хотя мы обнаружили, что большинство разработчиков заботятся о безопасности, но иногда они не понимают, как конкретный шаблон кода может привести к уязвимости, поэтому в электронной книге мы решили поделиться наиболее распространенными проблемами безопасности, которые мы видели во время помощи разным стартапам в защите своих приложений Laravel. С каждым примером атаки мы также покажем лучшие практики по защите вашего приложения от атак. Мы надеемся, что эта информация окажется полезной для вас и вашей команды разработчиков.

CyberPanda Team

SQL-инъекции

Laravel предоставляет надежный конструктор запросов (Query Builder) и Eloquent ORM. И, благодаря им, большинство запросов по-умолчанию защищены в приложениях, поэтому, например, запрос типа

будет автоматически защищен, так как Laravel переведет код в подготовленный оператор и выполнит.

Но разработчики обычно делают ошибки, полагая, что Laravel защищает от всех SQL-инъекций, хотя есть некоторые векторы атак, которые Laravel не может защитить.

Вот наиболее распространенные причины SQL-инъекций, которые мы видели в современных приложениях Laravel во время наших проверок безопасности.

1. SQL-инъекция через имя столбца

Первая распространенная ошибка, которую мы видим, заключается в том, что многие люди думают будто Laravel будет избегать любого параметра, переданного в Query Builder или Eloquent. Но, на самом деле, это не так безопасно передавать имена столбцов, управляемых пользователем, в конструктор запросов.

PDO does not support binding column names. Therefore, you should never allow user input to dictate the column names referenced by your queries, including «order by» columns, etc. If you must allow the user to select certain columns to query against, always validate the column names against a white-list of allowed columns.

Таким образом, следующий код будет уязвим для SQL-инъекции:

и если кто-то делает запрос со следующим значением параметра orderBy

под капотом будет выполнен следующий запрос и мы получим успешную SQL-инъекцию:

Важно отметить, что показанный вектор атаки исправлен в последней версии Laravel*, но, тем не менее, Laravel предупреждает разработчиков даже в свежей документации, чтобы они не передавали имена столбцов в Query Builder от пользователей без их добавления в белый список.

В общем, даже если нет возможности превратить настраиваемый столбец во внедренную SQL-инъекцию, мы по-прежнему не рекомендуем разрешать сортировку данных по любому столбцу, заданному пользователем, так как это может создать угрозу безопасности.

Рассмотрим пример, когда таблица «users» может иметь какой-то секретный столбец «secretAnswer», умный злоумышленник может вывести значение без необходимости SQL-инъекции.

2. SQL-инъекция с помощью правил валидации

Давайте посмотрим на следующий упрощенный код проверки

3. SQL-инъекция через необработанные запросы

Инъекция правил валидатора

Давайте посмотрим на следующий уязвимый код:

1. Сделать правило проверки необязательным

2. DDOS сервер путем создания злого правила проверки REGEX

Другой вектор атаки может заключаться в создании злой и уязвимой проверки Regex для ReDoS атаки и DDOS приложения. Например, следующий запрос потребляет много процессорного времени, и если несколько запросов отправляются одновременно, это может вызвать большой скачок нагрузки на ЦП сервера:

3. SQL-инъекция

Простейшей SQL-инъекцией было бы просто добавить дополнительное правило проверки передаваемое в запрос. Например:

Важно упомянуть, поскольку с помощью unique мы можем предоставить как настраиваемый столбец имени и значения (значения не проходят через привязку параметров PDO) возможность SQL-инъекции здесь не может быть ограничена просто упомянутым выше вектором атаки. Для получения дополнительных сведений ознакомьтесь с публикацией блога Laravel здесь.

Советы по профилактике:

Если вам нужно создать правило проверки на основе предоставленных данных (ID в нашем примере), обязательно приведите или подтвердите предоставленное значение, прежде чем помещать его в правило проверки.

XSS (межсайтовый скриптинг) в Laravel Blade

Об атаках XSS сообщалось и использовалось с 1990-х годов, но всё же иногда мы видим случаи, когда разработчики недооценивают опасность атаки из-за того факта, что он выполняется в браузере, а не на сервере. Но это может быть очень опасно, например, XSS-атака в панели администратора может позволить злоумышленнику выполнить такой код:

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

Теперь давайте посмотрим, каковы возможные векторы XSS-атак в Laravel.

Если вы используете Laravel Blade, он защищает вас от большинства XSS-атак, например, такая атака не сработает:

потому что оператор Blade << >> автоматически кодирует вывод. Итак, сервер отправит в браузер следующий правильно закодированный код:

что предотвратит атаку XSS. Но не всё Laravel (или любой другой фреймворк) может обработать за вас, вот несколько примеров XSS-атак, которые мы обнаружили наиболее распространенными во время наших проверок безопасности:

1. XSS через объявление

Советы по профилактике:

По возможности избегайте вывода данных в html без экранирования, предоставленных пользователем.

Если вы знаете, что в некоторых случаях данные могут содержать HTML, используйте такой пакет, как htmlpurifier. org, чтобы очистить HTML от JS и нежелательных тегов перед выводом контента.

2. XSS через атрибут a. href

Если вы выводите значение, указанное пользователем, в виде ссылки, покажем несколько примеров того, как это может превратиться в XSS-атаку:

Пример 1: Использование javascript:code

Пример 2: Использование данных в кодировке base64:

Обратите внимание, что этот будет работать только для фреймов не верхнего уровня.

код предупреждения («Hacked!») запускается, когда пользователь нажимает ссылку «Мой веб-сайт» в обоих случаях.

Советы по профилактике:

Проверяйте ссылки, предоставленные пользователем. В большинстве случаев вам нужно только разрешить http/https схемы;

В качестве дополнительного уровня безопасности перед выводом вы можете заменить любую ссылку, которая не начиная со схемы http/https значением «#broken-link».

3. XSS через кастомную директиву

Если в вашем Blade коде есть настраиваемые директивы, вам нужно вручную избежать любого вывода, который не должен отображаться в коде как HTML. Например, следующиая пользовательская директива уязвима, потому что переменная имени не закодирована, а Laravel ничего не может с этим поделать:

Советы по профилактике:

Уязвимости массового назначения в Laravel

Eloquent, как и многие другие ORM, имеет приятную особенность, позволяющую назначать свойства объекту без необходимости присваивать каждое значение индивидуально. Это хорошая функция, сохраняющая много времени и строк кода, но при неправильном использовании может привести к уязвимости.

Например, вот упрощённый пример небезопасного кода, который мы обнаружили во время проверки кода одного из наших клиентов:

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

Вот несколько советов о том, как предотвратить уязвимости массового назначения в Laravel.

Советы по профилактике:

1. Передавать модели только проверенные поля

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

2. Используйте белый список вместо черного

Отсутствие защиты от атак с использованием учетных данных

Итак, прежде всего, что такое атака с заполнением учетных данных? Это тип брутфорс атаки, где атаки отправляют пары имени пользователя и пароля, полученные в результате утечки других данных. Таким образом, например, злоумышленник получит миллионы логинов/паролей из утечек данных и автоматически попробует авторизоваться на вебсайте. Так как многие люди используют одно и то же сочетание имени пользователя и пароля на разных сайтах, согласно отчетам, в среднем, около 0,1-0,2% попыток будут успешными. Итак, если у веб-сайта около 1 миллиона пользователей, а злоумышленник использует 10 млн пар имен пользователей и паролей от других утечек данных, взломано будет примерно 10’000-20’000 аккаунтов. Чем больше база злоумышленника, тем потенциально взломанных учётных записей.

По-умолчанию Laravel Auth имеет базовую защиту от брутфорса, где проверяет, сколько запросов поступают с одного и того же IP-адреса для одного и того же пользователя и будут блокировать его, но нет защиты от вброса учетных данных. Вам нужно будет реализовать защиту самим, и вот несколько советов для вас:

1. Внедрить многофакторную аутентификацию

Вероятно, это одна из самых эффективных мер по улучшению безопасности вашего приложения. Symantec считает, что до 80% утечек данных могут можно предотвратить путем внедрения 2FA.

2. Ограничить количество запросов для входа в конечную точку с одного IP-адреса

Это не исключит атаку, если злоумышленник имеет доступ к широкому спектру IP, но определенно усложнит.

3. Добавить капчу в конечные точки аутентификации

Подобно блокировке IP, не будет обеспечена 100% защита, но опять же улучшится безопасность.

4. Обнаруживать, когда пользователь использует имя пользователя/пароль от других утечек данных

Если ваша компания типа FaceBook, вы можете реализовать что-то вроде этого, определенно потребует дополнительных ресурсов:

5. Внедрить надежную систему мониторинга и оповещения

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

Сломанный контроль доступа

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

Отсутствуют заголовки безопасности HTTP

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

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

Не отслеживание уязвимых пакетов в приложении

Каждый год в открытом исходном коде сообщается о десятках тысяч новых уязвимостей. И, например, одна из таких уязвимостей обошлась в размере 700 миллионов долларов штрафа и вреда репутации Equifax. Хакеры обнаружили, что один из серверов Equifax содержал уязвимую версию Apache Struts, о которой сообщалось 2 месяца назад но не было исправлено на сервере. Они использовали уязвимость для проникновения на серверы Equifax и украли личные записи 147,9 миллиона американцев.

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

Вывод

Реже, но, всё же, могут встречаться и следующие зависимости в зависимости от набора функциий и нужно понять их принцип работы, чтобы правильно прикрыть уязвимые места приложения:

Валидация в Laravel с примерами

Валидация в Laravel с примерами

Сегодняшняя тема – это инструкция по валидации в Laravel с примерами. Laravel фреймворк предоставляет множество различных способов валидации данных Вашего приложения. По умолчанию базовый контроллер Laravel использует трейт ValidateRequests, который обеспечивает удобный способ валидации входящего HTTP-запроса с помощью множества правил валидации.

Мы можем использовать валидацию в Laravel по-разному: либо внутри метода контроллера, либо с помощью класса FormRequest для валидации входящих запросов. В этом уроке мы рассмотрим все способы валидации в Laravel.

Валидация формы в Laravel

Первый шаг – установите последнею версию Laravel с помощью следующей команды.

Перейдите в папку проекта и откройте его в вашем IDE или редакторе кода.

Создайте файл FormController. php, используя следующую команду.

Создайте два метода внутри файла FormController. php.

Теперь напишите два маршрута в файле routes/web. php.

Создайте модель и файл миграции, используя следующую команду.

Напишите следующий код в файле миграции [timestamp] _create_forms_table. php, который находится в папке database/migrations.

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

Внутри папки resources/views, создайте файл layout. blade. php и добавьте в него следующий код.

Теперь в той же папке resources/views создайте файл с именем create. blade. php и добавьте в него следующий код.

Теперь, внутри контроллера FormController. php напишите функцию create().

Создание формы на Laravel

Написание логики валидации

Теперь мы можем написать логику валидации внутри функции store() из контроллера FormController.

Как видите, мы передали нужные правила валидации в метод validate(). Если валидация не пройдена, то ошибка сгенерируется автоматически. Если валидация пройдена, наш контроллер продолжит работу и сохранит данные в базе данных, и мы получим ответ в формате json.

Если мы отправим форму с пустыми полями, то мы в ответ получим ошибки.

Вывод ошибок валидации в Laravel

Остановка после первой неудачной проверки

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

Отображение ошибок валидации

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

Обратите внимание, что нам не нужно специально привязывать сообщения об ошибках к шаблону в нашем маршруте GET. Это потому, что Laravel будет проверять наличие ошибок в данных сессий и автоматически привязывать их к шаблону, если они доступны.

Проверяем, существуют ли ошибки в сессии, и выводим их на экран. Данный код добавляем внутри файла create. blade. php, в том месте где хотим, чтобы отображались ошибки.

Валидация через Form Request в Laravel

В приведенном выше примере мы написали правила валидации внутри контроллера. Но, мы также можем создать отдельный файл для написания правил валидации.

Для более сложных сценариев валидации Вы можете создать так называемые form requests. Form requests – это специальные классы, которые содержат логику валидации. Для создания класса form request, используйте Artisan-команду make: request.

В папке app/Http/Requests будет создан файл с именем FieldRequest. php.

Давайте добавим несколько правил валидации в методе rules().

Если Вы планируете использовать логику авторизации в другом месте Вашего приложения, верните true из метода authorize().

Итак, теперь Вам не нужно переписывать эти правила внутри метода store(), из контроллера FormController. php.

Вам необходимо импортировать пространство имен FieldRequest в файл FormController. php и передать FieldRequest в качестве инъекцию зависимости внутри функции store().

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

Настройка сообщений об ошибках

Вы можете настроить сообщения об ошибках, используемые form request, с помощью метода messages. Этот метод должен возвращать массив пар атрибутов / правил и соответствующие сообщения об ошибках.

Сохраните файл и снова отправьте форму без каких-либо значений, и Вы увидите эти сообщения об ошибках вместо используемых по умолчанию.

Изменение стандартных ошибок валидации в laravel

Создание валидаторов вручную

Если Вы не хотите использовать метод validate(), то Вы можете создать экземпляр валидатора вручную с помощью фасада Validator. Метод make() создает новый экземпляр валидатора.

Это даст нам тот же результат. Если Вы хотите создать экземпляр валидатора вручную, но в то же время воспользоваться автоматической переадресацией, Вы можете вызвать метод validate() в существующем экземпляре валидатора.

Для дополнительной информации о валидации, смотрите официальную документацию к Laravel.

На этом все, статья по валидации в Laravel 5.8 с примерами завершена.

Понравилась статья?

Тогда поделитесь ею с друзьями и подпишитесь на новые интересные статьи.

Источники:

https://laravel. demiart. ru/isklyucheniya-laravel-lovim-obrabatyvaem-i-sozdaem-sobstvennye/

https://habr. com/ru/post/518400/

https://sozdatisite. ru/laravel/validaciya-v-laravel-s-primerami

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: