ممارسات الأمان المتقدمة
ممارسات الأمان المتقدمة
الأمان له أهمية قصوى في تطبيقات الويب الحديثة. يغطي هذا الدرس ممارسات الأمان المتقدمة في Laravel، بما في ذلك الحماية ضد ثغرات OWASP Top 10، تنفيذ سياسات أمان المحتوى، وتقنيات التشفير المتقدمة.
OWASP Top 10 و Laravel
يمثل OWASP Top 10 المخاطر الأمنية الأكثر أهمية في تطبيقات الويب. توفر Laravel حماية مدمجة للكثير منها، لكن فهم كيفية عملها أمر أساسي.
<?php
// 1. منع حقن SQL - استخدم دائماً Eloquent أو Query Builder
// سيء - عرضة لحقن SQL
$users = DB::select("SELECT * FROM users WHERE email = '" . $request->email . "'");
// جيد - استخدام ربط المعاملات
$users = DB::select("SELECT * FROM users WHERE email = ?", [$request->email]);
// الأفضل - استخدام Eloquent
$users = User::where('email', $request->email)->get();
// 2. منع Cross-Site Scripting (XSS)
// Laravel يهرب تلقائياً الإخراج في قوالب Blade
// سيء - إخراج غير مهرب (استخدم فقط للمحتوى الموثوق)
{!! $userInput !!}
// جيد - إخراج مهرب (افتراضي)
{{ $userInput }}
// حماية إضافية من XSS لمدخلات المستخدم
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'comment' => ['required', 'string', 'max:1000', function ($attribute, $value, $fail) {
if (preg_match('/(script|iframe|object|embed|applet)/i', $value)) {
$fail('التعليق يحتوي على محتوى قد يكون خطيراً.');
}
}],
]);
// تنقية مدخلات HTML باستخدام HTMLPurifier
composer require mews/purifier
use Mews\Purifier\Facades\Purifier;
$clean = Purifier::clean($request->input('content'));
// 3. المصادقة المعطلة - تنفيذ مصادقة آمنة
// config/auth.php
return [
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60, // انتهاء صلاحية الرمز
'throttle' => 60, // تقييد المحاولات
],
],
];
// تنفيذ تقييد تسجيل الدخول
use Illuminate\Support\Facades\RateLimiter;
public function login(Request $request)
{
$key = 'login.' . $request->ip();
if (RateLimiter::tooManyAttempts($key, 5)) {
$seconds = RateLimiter::availableIn($key);
return response()->json([
'message' => "عدد كبير جداً من محاولات تسجيل الدخول. حاول مرة أخرى بعد {$seconds} ثانية."
], 429);
}
if (Auth::attempt($request->only('email', 'password'))) {
RateLimiter::clear($key);
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
RateLimiter::hit($key, 60);
return back()->withErrors(['email' => 'بيانات الاعتماد غير صحيحة']);
}
Hash في Laravel التي تنفذ خوارزميات تجزئة bcrypt أو Argon2.
الغوص العميق في حماية CSRF
هجمات Cross-Site Request Forgery (CSRF) تخدع المستخدمين لتنفيذ إجراءات غير مرغوب فيها. توفر Laravel حماية قوية من CSRF من خلال الرموز.
<?php
// يتم تطبيق وسيط CSRF تلقائياً على مسارات الويب
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'api/*', // استبعاد مسارات API
'webhooks/*', // استبعاد نقاط webhook
];
// لطلبات AJAX، قم بتضمين رمز CSRF في الرؤوس
// resources/js/bootstrap.js
window.axios.defaults.headers.common['X-CSRF-TOKEN'] =
document.querySelector('meta[name="csrf-token"]').getAttribute('content');
// في قوالب Blade
<meta name="csrf-token" content="{{ csrf_token() }}">
<form method="POST" action="/profile">
@csrf
<!-- حقول النموذج -->
</form>
// لانتحال الطريقة (PUT, PATCH, DELETE)
<form method="POST" action="/posts/1">
@csrf
@method('PUT')
<!-- حقول النموذج -->
</form>
// التحقق من CSRF المخصص في المتحكمات
use Illuminate\Support\Facades\Session;
public function verify(Request $request)
{
$token = $request->input('_token');
if (!hash_equals(Session::token(), $token)) {
abort(419, 'عدم تطابق رمز CSRF');
}
// معالجة الطلب
}
// تدوير رموز CSRF بعد العمليات الحساسة
public function updatePassword(Request $request)
{
// تحديث كلمة المرور
$request->session()->regenerateToken();
return redirect()->back();
}
سياسة أمان المحتوى (CSP)
سياسة أمان المحتوى هي معيار أمان يساعد في منع XSS وخطف النقرات وهجمات حقن الكود الأخرى من خلال تحديد الموارد التي يمكن تحميلها.
<?php
// app/Http/Middleware/SetSecurityHeaders.php
namespace App\Http\Middleware;
use Closure;
class SetSecurityHeaders
{
public function handle($request, Closure $next)
{
$response = $next($request);
// سياسة أمان المحتوى
$response->headers->set('Content-Security-Policy',
"default-src 'self'; " .
"script-src 'self' 'nonce-" . csp_nonce() . "' https://cdn.jsdelivr.net; " .
"style-src 'self' 'nonce-" . csp_nonce() . "' https://fonts.googleapis.com; " .
"img-src 'self' data: https:; " .
"font-src 'self' https://fonts.gstatic.com; " .
"connect-src 'self'; " .
"frame-ancestors 'none'; " .
"base-uri 'self'; " .
"form-action 'self';"
);
// X-Frame-Options (حماية من خطف النقرات)
$response->headers->set('X-Frame-Options', 'DENY');
// X-Content-Type-Options (حماية من استنشاق MIME)
$response->headers->set('X-Content-Type-Options', 'nosniff');
// X-XSS-Protection (حماية XSS القديمة)
$response->headers->set('X-XSS-Protection', '1; mode=block');
// Referrer-Policy
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
// Permissions-Policy (Feature Policy)
$response->headers->set('Permissions-Policy',
'geolocation=(), microphone=(), camera=()'
);
// HTTP Strict Transport Security (HSTS)
if ($request->secure()) {
$response->headers->set('Strict-Transport-Security',
'max-age=31536000; includeSubDomains; preload'
);
}
return $response;
}
}
// دالة مساعدة لـ CSP nonce
function csp_nonce()
{
return app('csp-nonce');
}
// التسجيل في AppServiceProvider
public function boot()
{
$this->app->singleton('csp-nonce', function () {
return base64_encode(random_bytes(16));
});
}
// استخدام nonce في قوالب Blade
<script nonce="{{ csp_nonce() }}">
// السكريبت المضمن
</script>
Content-Security-Policy-Report-Only.
ممارسات التشفير المتقدمة
توفر خدمات التشفير في Laravel واجهة بسيطة لتشفير وفك تشفير النص باستخدام OpenSSL مع تشفير AES-256 و AES-128.
<?php
use Illuminate\Support\Facades\Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
// التشفير/فك التشفير الأساسي
$encrypted = Crypt::encryptString('بيانات حساسة');
$decrypted = Crypt::decryptString($encrypted);
// تشفير الكائنات والمصفوفات
$encrypted = Crypt::encrypt([
'credit_card' => '4111111111111111',
'cvv' => '123',
]);
try {
$decrypted = Crypt::decrypt($encrypted);
} catch (DecryptException $e) {
// معالجة فشل فك التشفير
Log::error('فشل فك التشفير: ' . $e->getMessage());
}
// تشفير قاعدة البيانات باستخدام التحويلات
class User extends Model
{
protected $casts = [
'social_security_number' => 'encrypted',
'bank_account' => 'encrypted:array',
'credit_cards' => 'encrypted:collection',
];
}
// الوصول إلى البيانات المشفرة
$user = User::find(1);
$ssn = $user->social_security_number; // يتم فك التشفير تلقائياً
// تجزئة كلمات المرور والبيانات الحساسة
use Illuminate\Support\Facades\Hash;
// تجزئة كلمة المرور
$hashed = Hash::make('secret-password');
// التحقق من كلمة المرور
if (Hash::check('secret-password', $hashed)) {
// كلمة المرور مطابقة
}
// التحقق مما إذا كانت إعادة التجزئة مطلوبة (تم تحديث الخوارزمية)
if (Hash::needsRehash($hashed)) {
$hashed = Hash::make('secret-password');
}
// التوقيع والتحقق من سلامة البيانات
use Illuminate\Support\Facades\URL;
// إنشاء رابط موقع (تنتهي صلاحيته في 30 دقيقة)
$url = URL::temporarySignedRoute(
'download', now()->addMinutes(30), ['file' => 'report.pdf']
);
// التحقق من الرابط الموقع في المتحكم
public function download(Request $request)
{
if (!$request->hasValidSignature()) {
abort(401, 'رابط تنزيل غير صالح أو منتهي الصلاحية');
}
return response()->download(storage_path('reports/' . $request->file));
}
// تنفيذ المصادقة الثنائية
use PragmaRX\Google2FA\Google2FA;
$google2fa = new Google2FA();
// توليد مفتاح سري
$secretKey = $google2fa->generateSecretKey();
// توليد رابط رمز QR
$qrCodeUrl = $google2fa->getQRCodeUrl(
config('app.name'),
auth()->user()->email,
$secretKey
);
// التحقق من رمز 2FA
$valid = $google2fa->verifyKey($user->google2fa_secret, $request->input('token'));
config/app.php (أو APP_KEY في .env) بالغ الأهمية. إذا فقدته، ستصبح جميع البيانات المشفرة غير قابلة للاسترداد. احتفظ بنسخة احتياطية من مفتاح التشفير بشكل آمن ودوره بشكل دوري.
مصادقة API الآمنة
<?php
// مصادقة رمز Sanctum API مع القدرات
use Laravel\Sanctum\HasApiTokens;
class User extends Model
{
use HasApiTokens;
}
// إنشاء رموز مع قدرات محددة
$token = $user->createToken('mobile-app', [
'posts:read',
'posts:create',
'comments:read',
])->plainTextToken;
// حماية المسارات بالقدرات
Route::middleware(['auth:sanctum', 'ability:posts:create'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
});
// التحقق من القدرات في المتحكمات
public function update(Request $request, Post $post)
{
if (!$request->user()->tokenCan('posts:update')) {
return response()->json(['error' => 'غير مصرح'], 403);
}
// تحديث المنشور
}
// تنفيذ مصادقة مفتاح API
// app/Http/Middleware/CheckApiKey.php
namespace App\Http\Middleware;
use Closure;
class CheckApiKey
{
public function handle($request, Closure $next)
{
$apiKey = $request->header('X-API-Key');
if (!$apiKey || !$this->isValidApiKey($apiKey)) {
return response()->json(['error' => 'مفتاح API غير صالح'], 401);
}
return $next($request);
}
private function isValidApiKey($key)
{
return hash_equals(config('services.api.key'), $key);
}
}
// تحديد معدل طلبات API
// app/Providers/RouteServiceProvider.php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
RateLimiter::for('sensitive', function (Request $request) {
return Limit::perMinute(5)
->by($request->user()->id)
->response(function () {
return response()->json([
'error' => 'عدد كبير جداً من المحاولات. يرجى المحاولة مرة أخرى لاحقاً.'
], 429);
});
});
}
تمرين 1: نظام رفع ملفات آمن
أنشئ نظام رفع ملفات آمن مع الميزات التالية:
- التحقق من أنواع الملفات (نهج القائمة البيضاء) وحدود الحجم
- فحص الملفات المرفوعة بحثاً عن البرامج الضارة باستخدام ClamAV أو ما شابه
- تخزين الملفات خارج الدليل العام
- توليد روابط موقعة مع انتهاء الصلاحية للتنزيلات
- تنفيذ وظيفة قائمة انتظار لفحص الفيروسات
- تسجيل جميع محاولات الرفع والتنزيل مع IP ومعلومات المستخدم
تمرين 2: المصادقة متعددة العوامل
نفذ نظام 2FA كامل:
- السماح للمستخدمين بتمكين/تعطيل 2FA عبر الإعدادات
- توليد وعرض رموز QR لتطبيقات المصادقة
- توفير رموز احتياطية لاستعادة الحساب
- تنفيذ تحدي 2FA أثناء تسجيل الدخول
- إضافة وظيفة "تذكر هذا الجهاز" لمدة 30 يوماً
- إرسال إشعارات بريد إلكتروني عند تمكين/تعطيل 2FA
تمرين 3: نظام تدقيق الأمان
ابنِ نظام تدقيق أمان شامل:
- تسجيل جميع محاولات المصادقة (الناجحة والفاشلة)
- تتبع عناوين IP ووكلاء المستخدم
- كشف الأنماط المشبوهة (عمليات تسجيل دخول فاشلة متعددة، مواقع غير عادية)
- إرسال تنبيهات للأحداث الأمنية عبر البريد الإلكتروني/Slack
- إنشاء لوحة تحكم تظهر الأحداث الأمنية الأخيرة
- تنفيذ قفل الحساب التلقائي بعد الحد الأدنى
- توفير تصدير سجل التدقيق بتنسيق CSV/JSON