Блог
Кар'єра
Вакансії Компанії
Навчання
Співбесіди Тестування Відео
Екосистема
Пакети Ресурси
Інше
Події Про нас

Питання на співбесіді: Безпека

Найпопулярніші питання з реальних Laravel/PHP співбесід для всіх рівнів

5 питань

CSRF (Cross-Site Request Forgery) - це атака, коли сторонній сайт змушує браузер автентифікованого користувача надіслати небажаний запит на ваш застосунок, використовуючи його активну сесію (наприклад, прихована форма, що переказує гроші).

Як Laravel захищає: для кожної активної сесії генерується унікальний CSRF-токен. Middleware ValidateCsrfToken перевіряє цей токен для всіх «небезпечних» методів - POST, PUT, PATCH, DELETE. Запити без валідного токена відхиляються з кодом 419.

У формах додають директиву @csrf, яка вставляє прихований інпут із токеном:

<form method="POST" action="/profile">
    @csrf
    <input name="email" type="email">
    <button>Зберегти</button>
</form>

Для AJAX токен передають у заголовку X-CSRF-TOKEN (зазвичай із <meta name="csrf-token">):

fetch('/profile', {
    method: 'POST',
    headers: { 'X-CSRF-TOKEN': token },
});

GET-запити токена не потребують (вони мають бути безпечними й не змінювати стан). Для stateless API на токенах (Sanctum) CSRF не застосовується.

Докладніше в документації: CSRF-захист

Mass Assignment - це присвоєння групи атрибутів моделі з масиву (наприклад, Model::create($request->all())). Вразливість виникає, коли користувач підкидає неочікувані поля (скажімо, is_admin).

Захист - білий або чорний список у моделі:

protected $fillable = ['title', 'body']; // дозволено лише ці
// або
protected $guarded = ['id', 'is_admin']; // заборонено ці

Найкраща практика: не передавати $request->all(), а валідувати й передавати $request->validated().

Докладніше в документації: Mass Assignment

Signed URL - посилання з криптографічним підписом у query-рядку. Якщо хтось змінить URL, підпис стане недійсним - підробка неможлива без APP_KEY.

// згенерувати
URL::signedRoute('unsubscribe', ['user' => $id]);
URL::temporarySignedRoute('download', now()->addMinutes(30), ['file' => $id]);
// перевірити (middleware або вручну)
Route::get('/download/{file}', ...)->middleware('signed');

Застосування: посилання-відписки в листах, тимчасові посилання на скачування, підтвердження email - там, де потрібен захищений доступ без автентифікації. temporarySignedRoute додає термін дії.

Докладніше в документації: Підписані URL

  • Паролі - лише одностороннє хешування (Bcrypt/Argon2): Hash::make() / Hash::check(). Ніколи не шифрування й не власні алгоритми.
  • PII (двостороннє) - Crypt::encryptString() або каст encrypted на атрибуті моделі:
    protected $casts = ['ssn' => 'encrypted'];
    
  • Ключі та секрети - у .env / секретних сховищах (AWS Secrets Manager, Vault), не в git. Ротація APP_KEY потребує перешифрування.
  • Транзит - лише HTTPS/TLS.
  • Логи - маскувати PII; уникати dd() у проді.
  • Доступ - принцип найменших привілеїв, audit log (наприклад, spatie/laravel-activitylog).

Докладніше в документації: Шифрування

CSP - HTTP-заголовок, що визначає, з яких джерел дозволено завантажувати ресурси (скрипти, стилі, зображення). Це потужний захист від XSS: навіть якщо зловмисник впровадить <script>, браузер не виконає його, якщо джерело не дозволене.

Content-Security-Policy: default-src 'self';
    script-src 'self' https://cdn.example.com;
    img-src 'self' data:;

У Laravel заголовок додають через middleware (вручну або пакетом на кшталт spatie/laravel-csp).

Практики:

  • Уникати 'unsafe-inline' - використовувати nonce для інлайн-скриптів.
  • Спершу режим report-only (Content-Security-Policy-Report-Only) зі збором звітів, щоб не зламати сайт.