Просьба оставить комментарий





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

среда, 30 ноября 2022 г.

Иногда redis-server не запускается, выдавая ошибку: signal-handler Received SIGTERM scheduling shutdown

 Иногда redis-server не запускается, выдавая ошибку:

signal-handler Received SIGTERM scheduling shutdown...

Увидеть её можно в логе, например так:
tail -f /var/log/redis/redis.log

Простое решение - увеличить лимиты:
sysctl vm.overcommit_memory=1
sysctl -w net.core.somaxconn=65535

Если warning'ов нет, а ошибка осталась, то вариантом решения может быть установка увеличенных таймаутов. Для этого в файл - /etc/systemd/system/redis.service.d/limit.conf необходимо добавить следующие строки:
[Service]
TimeoutStartSec=300s
TimeoutStopSec=90s

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

понедельник, 17 октября 2022 г.

5 советов по упрощению кода Laravel

 

1. Упростите операторы if/else

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

2. Используйте Laravel exists()вместо count()проверки существования экземпляра модели.

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

3. Используйте modelKeys()для получения первичных ключей вместоpluck()

Когда мы обращаемся к модели и пытаемся получить первичные ключи или идентификаторы модели, самый простой способ сделать это — использовать pluck()для получения определенных полей. Но если все, к чему вы хотите получить доступ, это ключи модели или первичные ключи и ничего больше (возможно, для синхронизации или подключения к другой модели), вы можете использовать встроенный методmodelKeys()

4. Не создавайте ненужных переменных и пытайтесь возвращать значения напрямую

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

5. Воспользуйтесь преимуществами коллекций Laravel вместо манипулирования массивами вручную

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

Функционально эти два подхода одинаковы, но использование коллекций Laravel дает вам доступ к множеству методов, которые вы можете выполнять с отдельными коллекциями или элементами в коллекции. Вот некоторые примеры:

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


Топ-8 плохих практик безопасности в Laravel, о которых вы должны знать

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

Здесь я перечислю 8 самых плохих методов обеспечения безопасности с советами , как их избежать.

  • SQL-инъекция через имена столбцов и необработанные запросы.
  • SQL-инъекция через правила проверки.
  • Внедрение правил проверки.
  • Использование GET для не-GET-маршрутов.
  • Использование $request->all().
  • Забыть режим отладки в продакшене.
  • XSS с использованием неэкранированного оператора данных.
  • XSS с использованием атрибута href.

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

Очень распространенная практика передачи управляемых пользователем столбцов в Query Builder, думая, что Laravel проверяет их с помощью привязки параметров PDO, но, как упоминается в документации Laravel :

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

Чтобы было понятно, предположим, что у нас есть следующий запрос:

Product::where('brand_id',$request->brand_id) 
->orderBy($request->orderBy)
->get();

поэтому, если пользователь ввел что-то вроде price->”%27))%23injection , запрос будет переведен следующим образом:

выберите * из `продуктов`, где brand_id =? упорядочить по json_unquote( 
json_extract(`price`, '$.""')
) #injection"')) asc

Что делать: как упоминается в документации Laravel:

если необходимо разрешить пользователю выбирать определенные столбцы для запроса, всегда проверяйте имена столбцов по разрешенным столбцам из белого списка.

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

Так что не забудьте использовать привязку параметров

SQL-инъекция через правила проверки

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

Эта практика распространена при проверке запроса на обновление и предоставлении идентификатора из самого запроса. Вот пример.

$id = $запрос->id; 
$rules = [
'email'=>'email|обязательный|уникальный: пользователи, электронная почта,'.$id
];
$validator = Validator::make($request->all(),$rules);

Там мы видим, что это уязвимость безопасности, которая позволяет хакеру внедрить оператор SQL.

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

Внедрение правил проверки:

1- Сделайте правило необязательным:
как в предыдущем примере

$id = $запрос->id; 
$rules = [
'email'=>'email|обязательный|уникальный: пользователи, электронная почта,'.$id
];
$validator = Validator::make($request->all(),$rules);

пользователь передал следующее:

10|иногда

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

2- Проверка регулярного выражения DDOS:

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

1|регулярное выражение:(*а){10000}Предыдущее регулярное выражение потребляло много ресурсов, а несколько запросов с одной и той же полезной нагрузкой приводили к перегрузке ЦП.

Что вам следует делать: Как упоминалось ранее: просто не создавайте правила проверки на основе вашей пользовательской записи, если вы вынуждены, просто проверьте значения вручную, а затем создайте свое правило.

Использование GET для не-GET-маршрутов

Как упоминалось в документации Laravel:

Каждый раз, когда вы определяете HTML-форму «POST», «PUT», «PATCH» или «DELETE» в своем приложении, вы должны включить в форму скрытое _tokenполе CSRF, чтобы промежуточное программное обеспечение защиты CSRF могло проверить запрос.

По умолчанию Laravel не выполнит любой запрос от упомянутых действий без поля _token.

Так почему мы упомянули об этом?
За свою карьеру я видел, как многие разработчики определяют маршрут GET для не-GET действий, как, например, этот маршрут

Route::get('product/{id}/delete','ProductController@delete);

Для предыдущего маршрута, если он был вызван, он выполнит действие удаления, потому что laravel не будет проверять поле _token, и действие будет выполнено.

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

Использование $request->all() для создания модели

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

\Приложение\Модели\User.php

<?php 
namespace App\Models;
class User extends Authenticatable
{

protected $fillable = [
'usernamename',
'email',
'password',
'role'
];

}

UserRequest.php

<?php 

namespace App\Http\Requests;

class UserRequest extends FormRequest
{

public function rules()
{
return [
'username'=>'required',
'email'=>'email|required|unique:users,email'
'password'=>'required|min:8'
];
}
}

UserController.php

<?php 

namespace App\Http\Controllers;

класс UserController расширяет контроллер
{
общедоступное хранилище функций (UserRequest $ request)
{
User :: create ( $ request-> all () );
вернуть ответ()->json();
}
}

Многие разработчики думают, что при использовании проверки FormRequest.php $request->all() будет возвращать только проверенные данные, НЕПРАВИЛЬНО
для предыдущего примера, если пользователь отправит полезную нагрузку как:

{ 
"имя пользователя": "тест",
"электронная почта": "email@email.com",
"пароль": "Pssw0rd",
"роль": "admin"
}

Пользователь Test будет администратором и бум.

Это простой пример, так что продолжайте свое воображение.

Что делать:
вместо использования $request->all()
вы можете использовать $request->validated() или $request->only().

Забыть включенный режим отладки в производстве

Итак, мы сделали все возможное, чтобы сделать приложение безопасным. И последнее: НЕ ЗАБЫВАЙТЕ APP_DBUG=TRUE в файле .env.

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

например, я создал функцию для исключения исключения следующим образом

На странице исключений было открыто содержимое моего файла модели пользователя:

Что делать:
просто установить для APP_DEBUG в файле .env значение false.
если вы хотите отслеживать журнал исключений, просто добавьте следующий код в файл App\Exceptions\Handler.php:

защищенная функция LogException(\Exception $ex){ 
Log::error("Сообщение: ".$ex->getMessage());
Log::error("Строка: ".$ex->getLine());
Log::error("Файл: ".$ex->getFile());
}
public function register(){
$this->reportable(function (Throwable $e) {
$this->LogException($exception);
});
}

XSS с использованием неэкранированного оператора данных

По умолчанию операторы Blade {{ }}автоматически отправляются через htmlspecialcharsфункцию PHP для предотвращения XSS-атак. Если вы не хотите, чтобы ваши данные были экранированы, вы можете использовать следующий синтаксис:
{!! $data !!}

это большая уязвимость XSS, позволяющая не экранировать пользовательские данные в представлении блейда.
чтобы увидеть разницу, давайте посмотрим на следующий пример:

$data = '<b>Полужирный</b>'; 
-----------------------
<body>
это экранировано {{$data}}
это не экранировано {!! $данные !!}
</body>

страница будет следующей

например, если $data был пользовательским вводом, например:

$data = '<script>alert("XSS-атака");</script>';

результат будет:

Что делать:
будьте осторожны и не используйте неэкранированный оператор {!! !!} с данными, предоставленными пользователем, Никогда не доверяйте вводу пользователя

XSS с использованием атрибута href

не только {!! !!} позволяет выполнять вредоносный код на стороне клиента, но также это можно сделать с помощью атрибута href в теге <a>.

так, например, ваше приложение позволяет пользователям обмениваться ссылками, и вы создали тег <a> для отображения ссылок и перенаправления пользователей на ссылки, если один из пользователей сохранил вредоносный код в качестве ссылки, это может привести к несчастному концу:

$data = 'javascript:alert("XSS-атака");'; 
--------------------------------------------------
.blade-файл:
<a href="{{$data}}">Нажмите здесь, чтобы увидеть дополнительную ссылку</a>

Итак, когда пользователь нажимает на него:

Что вам следует делать:
если пользователи предоставляют ссылки для размещения ваших файлов блейдов и динамического совместного использования, вы можете просто проверить схему http/https перед сохранением ссылки.