3.4الأمن : حقن SQL (SQL injection)، XSS، CSRF، التجزئة (hashing)
الأساسي في 30 ثانية
- لا ثقة أبدا بالمدخلات : كل بيانة خارجية مشبوهة — تحققوا، ثم عالجوا حسب السياق (SQL، HTML، بريد).
- ثلاث ثغرات، وثلاثة منعكسات : حقن SQL ← استعلامات محضرة ؛ وXSS ← htmlspecialchars() عند العرض ؛ وCSRF ← رمز وحيد مُتحقَّق منه + SameSite.
- كلمات السر أبدا بشكل واضح : password_hash() عند التخزين، وpassword_verify() عند الدخول — ولا كلمة سر داخل الكود.
حالة مصغرة متسلسلة — رياد يدقق متجره قبل الإطلاق
رياد، مطور وب في قسنطينة، يستعد لإطلاق متجره : تعليقات معروضة خاما، ونموذج طلب دون رمز، وكلمات سر زبناء واضحة في القاعدة. صحح كل شيء : htmlspecialchars() على كل عرض، ورمز CSRF وحيد لكل نموذج مُتحقَّق منه عند الإرسال، و password_hash() عند التسجيل و password_verify() عند الدخول. اجتاز التدقيق بالأخضر قبل الافتتاح.
الحلقة الأخيرة لخيط رياد — من القاعدة إلى الكائنات حتى التحصين الكامل.
1. حقن SQL و XSS و CSRF : الآليات والدروع
الأمن دائم، وليس خيارا أخيرا، حول مبدأ : لا ثقة أبدا بالمدخلات. (1) حقن SQL (SQL injection) (يُنظر 3-1) : SQL محقون عبر بيانات مدمجة — الدرع : استعلامات PDO محضرة، دائما. (2) XSS : جافاسكريبت محقونة تُنفَّذ في متصفح الآخرين حين نعرض بيانات غير موثوقة دون هروب (سرقة جلسة، تشويه) — الدرع : الهروب عند العرض بـ htmlspecialchars()، دائما، لكل بيانة غير موثوقة.
(3) CSRF : إجبار مستعمل متصل على تنفيذ فعل دون علمه عبر طلب مزور من موقع آخر — الدرع : رموز CSRF (قيمة وحيدة وسرية لكل نموذج، تُتحقَّق عند الإرسال) و cookie بـ SameSite. يضيف رياد رمزا مولدا بـ random_bytes() في حقل مخفي لكل نموذج حساس ويقارنه في الجلسة قبل أي معالجة.
2. التجزئة و HTTPS والأسرار : نظافة غير قابلة للتفاوض
تُخزَّن كلمات السر مُجزَّأة، أبدا بشكل واضح : password_hash() عند التسجيل (خوارزمية آمنة، وملح وتكلفة مدمجان)، وpassword_verify() عند الدخول. ولا كلمة سر واضحة ولا داخل الكود، لا في اللقطات ولا في الرسائل — هذا غير قابل للتفاوض.
باقي النظافة : HTTPS في الإنتاج (التشفير)، وأسرار خارج الكود (مفاتيح وكلمات سر القاعدة في متغيرات البيئة)، وأخطاء مفصلة لا تُعرَض أبدا في الإنتاج (تُسجَّل، ولا تُكشَف)، وPHP والاعتمادات محدَّثة، وتفويض مُتحقَّق منه (لا المصادقة وحدها). وللتكوين : OWASP Top 10، مرجع ثغرات الوب.
🔎 مثال ملموس — XSS مُحيَّد، و CSRF مُتحقَّق منه، وكلمة سر مُجزَّأة
يؤمن رياد عرض اسم مستعار، ونموذجا، والتسجيل.
Bonjour, ' . htmlspecialchars($pseudo, ENT_QUOTES, 'UTF-8') . '';
// 2) CSRF : رمز وحيد في الجلسة، وحقل مخفي، وتحقق
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
// في النموذج :
if (!hash_equals($_SESSION['csrf'], $_POST['csrf'] ?? '')) {
http_response_code(403);
exit('Requete refusee.');
}
// 3) التجزئة : أبدا بشكل واضح
$hash = password_hash($motDePasseSaisi, PASSWORD_DEFAULT);
// ... تخزين $hash في القاعدة عبر استعلام محضر ...
$ok = password_verify($motDePasseSaisi, $hashStocke);
القراءة : هروب عند العرض، ورمز مقارَن بـ hash_equals، وتجزئة ثم تحقق.
الدرس : ثلاث حركات قصيرة تغلق ثلاث ثغرات خطيرة.
مفردات القسم
- لا ثقة أبدا بالمدخلات
- مبدأ عابر : كل بيانة خارجية قد تكون خبيثة — تحققوا ثم عالجوا حسب السياق.
مثال بسيط: يتحقق رياد من البريد قبل كل استعمال.
ما ليس كذلك: العرض كما هو « لأنه من نموذجي ».
رد فعل: مشتبه افتراضيا، ومُتحقَّق منه قبل الاستعمال.
- حقن SQL ← المحضرة
- SQL محقون عبر الدمج ؛ الدرع : دائما استعلامات PDO محضرة، ولا دمج أبدا.
مثال بسيط: prepare/execute متجر رياد.
ما ليس كذلك: دمج « مؤقت ».
رد فعل: علامات + execute، دون استثناء.
- XSS ← htmlspecialchars
- سكريبت محقون يُنفَّذ عند زوار آخرين ؛ الدرع : هروب كل بيانة غير موثوقة عند العرض.
مثال بسيط: الاسم المستعار المعلَّق معروضا كنص غير مؤذٍ.
ما ليس كذلك: echo مباشر لحقل مستعمل.
رد فعل: htmlspecialchars() على كل عرض غير موثوق.
- CSRF ← الرموز
- فعل مفروض دون علم متصل ؛ الدرع : رمز وحيد لكل نموذج مُتحقَّق منه + cookie بـ SameSite.
مثال بسيط: الحقل المخفي المقارَن في الجلسة عند رياد.
ما ليس كذلك: نموذج حساس دون أي رمز.
رد فعل: رمز على كل فعل حساس.
- التجزئة / HTTPS / الأسرار
- كلمات سر مُجزَّأة (password_hash/verify، أبدا بشكل واضح) ؛ و HTTPS ؛ وأسرار في البيئة ؛ وأخطاء مخفية في الإنتاج ؛ ومحدَّث.
مثال بسيط: تسجيل رياد المُجزَّأ ودخوله المُتحقَّق منه.
ما ليس كذلك: كلمة سر مخزنة مقروءة في القاعدة.
رد فعل: لا سر واضح، في أي مكان.
في التطبيق — تأمين تطبيق PHP
- ضد حقن SQL : استعلامات محضرة (PDO) دائما — تأكدوا أن لا بيانة مدمجة في SQL.
- ضد XSS : اهربوا كل بيانة معروضة بـ htmlspecialchars() (تعليقات، أسماء مستعارة، بيانات القاعدة).
- ضد CSRF : أضيفوا رمز CSRF (وحيد، سري) في نماذجكم وتحققوا منه عند الإرسال ؛ واستعملوا SameSite على cookies.
- جزئوا كلمات السر (password_hash/verify)، واستعملوا HTTPS، ودبروا الأسرار خارج الكود، ولا تعرضوا الأخطاء في الإنتاج، وأبقوا PHP/الاعتمادات محدَّثة.
نص جاهز للقول — عرض تدقيق الأمن (30 ثانية)
« قبل الإطلاق : استعلامات محضرة في كل مكان، و htmlspecialchars على كل عرض، ورمز CSRF مُتحقَّق منه على النماذج الحساسة، وكلمات سر مُجزَّأة بـ password_hash ومُتحقَّق منها بـ password_verify. الأسرار في البيئة، و HTTPS في الإنتاج. »
يُقال في مراجعة ما قبل الإطلاق ؛ وتُعرَض الحركات الأربع في الكود.
نموذج نسخ-لصق — تسجيل ودخول آمنان
prepare('INSERT INTO utilisateurs (email, mot_de_passe) VALUES (:email, :hash)');
$stmt->execute(['email' => $email, 'hash' => $hash]);
// الدخول : القراءة بمحضر، والتحقق من التجزئة
$stmt = $pdo->prepare('SELECT id, mot_de_passe FROM utilisateurs WHERE email = :email');
$stmt->execute(['email' => $emailSaisi]);
$utilisateur = $stmt->fetch();
if ($utilisateur && password_verify($motDePasseSaisi, $utilisateur['mot_de_passe'])) {
session_regenerate_id(true);
$_SESSION['utilisateur_id'] = $utilisateur['id'];
}
// العرض : الهروب دائما
$pseudoAffiche = htmlspecialchars($pseudo, ENT_QUOTES, 'UTF-8');
مستقل
المحضرة + htmlspecialchars + التجزئة : يكفي الثلاثي للإطلاق دون خطأ جسيم.
مقاولة صغيرة في قسنطينة
يضيف رياد رموز CSRF لأوامر الشراء قبل الافتتاح.
فريق منتج
فرض قائمة الحركات الأربع في مراجعة كود منهجية.
مبتدئ
هذا الأسبوع : عرض مُهرَب واحد وتسجيل مُجزَّأ واحد.
✓ ممارسات جيدة
- التفكير أمنا منذ التصميم، في كل طبقة (مدخَل، SQL، HTML، فعل، تخزين).
- استعمال الأدوات المُجرَّبة (المحضرة، htmlspecialchars، password_hash، الرموز) بدل الخاص.
- التكوين المستمر (OWASP Top 10) : تتطور الهجمات.
✗ أخطاء شائعة
- عرض بيانة من « قاعدتي الخاصة » دون هروب (فهي من مستعملين).
- نسيان رمز CSRF على فعل حساس (طلب، حذف).
- عرض الأخطاء المفصلة في الإنتاج (معلومات مُكشَفَة).
النقاط الأساسية
- الأمن دائم، حول مبدأ : لا ثقة أبدا بالمدخلات (كل الخارج مشتبه).
- حقن SQL ← المحضرة (لا دمج أبدا). XSS ← الهروب بـ htmlspecialchars(). CSRF ← الرموز + SameSite.
- كلمات سر مُجزَّأة (password_hash/verify، أبدا واضحة ولا داخل الكود). HTTPS، وأسرار خارج الكود، وأخطاء مخفية في الإنتاج، ومحدَّث.
- أدوات مُجرَّبة + تكوين (OWASP Top 10). موقع غير مؤمَّن يعرض مستعمليه للخطر — مسؤولية مهنية.
تحدي 48 ساعة — طبّق غدا
أضيفوا رمز CSRF واحدا مُتحقَّقا منه إلى نموذج، واهربوا 3 عروض وحولوا تخزينا واحدا إلى password_hash.
- أذكر الدروع الأربعة دون تردد.
- لا بيانة مدمجة ولا معروضة خاما.
- لا كلمة سر واضحة في كودي.
أسئلة شائعة
XSS و CSRF : عمليا، كيف نحتمي منهما ؟
XSS : يدس مهاجم جافاسكريبت في حقل (تعليق، اسم مستعار) معروض دون هروب — فيُنفَّذ عند الزوار (سرقة جلسة، تحويل). الدرع : htmlspecialchars() على كل بيانة غير موثوقة قبل العرض (فيصبح السكريبت نصا غير مؤذٍ). وCSRF : طلب مزور من موقع آخر يجعل متصلا يفعل دون علمه (تغيير بريد، طلب). الدرع : رمز وحيد وسري لكل نموذج، يُتحقَّق منه عند الإرسال (+ SameSite على cookies). آليتان مختلفتان، ودرعان منهجيان.
بماذا نبدأ في الأمن، وأي عقلية نتبنى ؟
العقلية : « لا ثقة أبدا بالمدخلات » — كل الخارج مشتبه (حتى « واجهتكم »، القابلة للالتفاف بطلبات مباشرة). الأسس عالية الأثر : (1) حقن SQL ← المحضرة، و(2) XSS ← الهروب، و(3) CSRF ← الرموز، و(4) كلمات السر ← التجزئة، و(5) HTTPS، و(6) أسرار خارج الكود، و(7) أخطاء مخفية في الإنتاج، و(8) التفويض (الحقوق، لا الدخول فقط)، و(9) رفوعات مقفلة. ثم OWASP Top 10 لهيكلة الباقي.
ينشر زائر اسما مستعارا فيه جافاسكريبت. المنعكس الصحيح ؟