تنظيف مدخلات المستخدم في PHP: أهم الأخطاء والحماية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

"أنا فقط أفلت علامات الاقتباس": لماذا كودك عرضة للاختراق

\n\n

إذا كنت قد بحثت يومًا عن "كيفية تنظيف مدخلات المستخدم في PHP؟"، فأنت لست وحدك. هذا السؤال على Stack Overflow حصد مئات الآلاف من المشاهدات. ولا عجب: موضوع الأمان من أكثر المواضيع سخونة في تطوير الويب.

\n\n

لكن المفارقة هي أن معظم الإجابات على هذا السؤال إما قديمة أو خطيرة. لا يزال المطورون يكتبون شيئًا مثل mysql_real_escape_string() (التي اختفت منذ 10 سنوات) أو ببساطة يحذفون الأحرف "الخطيرة". تنبيه: هذا لا يعمل.

\n\n

في هذا المقال، سنستعرض أهم 5 أخطاء في تنظيف مدخلات المستخدم في PHP والتي تجعل موقعك مثل الغربال، وسنوضح كيفية إصلاحها نهائيًا.

\n\n

الخطأ رقم 1: الإيمان الأعمى بـ"التنظيف" كحل سحري

\n\n

أكبر خطأ هو الاعتقاد بوجود دالة واحدة "تنظف" أي بيانات. إليك كودًا نموذجيًا لمبتدئ:

\n\n
<?php\n$name = $_POST['name'];\n$name = strip_tags($name);\n$name = addslashes($name);\n// هل البيانات آمنة الآن؟ لا!\n?>
\n\n

المشكلة أن السياقات المختلفة تتطلب معالجة مختلفة. التحقق من الصحة (Validation) والتنظيف (Sanitization) ليسا نفس الشيء. وهناك أيضًا ترميز المخرجات (Output Escaping) الذي يحدث في مكان آخر.

\n\n

الحل الصحيح: حدد ما تفعله بالبيانات في كل مرحلة. لقاعدة البيانات شيء، ولـ HTML شيء آخر، ولـ JSON شيء ثالث.

\n\n

الخطأ رقم 2: استخدام دوال قديمة (أو استخدامها بشكل خاطئ)

\n\n

لنستعرض "الديناصورات" في أمان PHP:

\n\n
    \n
  • mysql_real_escape_string() — أُزيلت في PHP 7.0. انسَ أمرها.
  • \n
  • addslashes() — لا تحمي من جميع هجمات حقن SQL، خاصة مع الترميزات متعددة البايت.
  • \n
  • strip_tags() — تزيل الوسوم لكنها لا ترمز المخرجات. هجمات XSS لا تزال ممكنة عبر الخصائص.
  • \n
\n\n

مثال على كود خطير لا يزال موجودًا:

\n\n
<?php\n$id = $_GET['id'];\n$id = addslashes($id);\n$query = "SELECT * FROM users WHERE id = '$id'";\n// إذا كانت id = 1 OR 1=1 -- تم اختراقك\n?>
\n\n

الحل الصحيح: استخدم الاستعلامات المحضرة (Prepared Statements). هذه هي الطريقة الوحيدة الموثوقة للحماية من حقن SQL.

\n\n
<?php\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");\n$stmt->execute(['id' => $_GET['id']]);\n?>
\n\n

أرأيت؟ لا حاجة لتنظيف SQL. فقط معاملات. قاعدة البيانات نفسها ستفصل بين البيانات والأوامر.

\n\n

الخطأ رقم 3: الخلط بين التحقق من الصحة والتنظيف

\n\n

كثيرون يعتقدون: "سأحذف جميع الأحرف المشبوهة وسأكون آمنًا". لكن هذا يكسر منطق التطبيق. تخيل أن المستخدم أدخل كلمة مرور P@ssw0rd!، وقمت بحذف الرمزين @ و !. ستصبح كلمة المرور Pssw0rd — ولن يتمكن المستخدم من تسجيل الدخول بعد الآن.

\n\n

التحقق من الصحة (Validation) — يتحقق مما إذا كان الإدخال يطابق التنسيق المتوقع (بريد إلكتروني، رقم، رابط). إذا لم يطابق، نرفضه.

\n\n

التنظيف (Sanitization) — يزيل أو يعدل الأحرف غير المرغوب فيها، ولكن فقط عندما يكون ذلك ضروريًا حقًا (مثل اسم ملف).

\n\n

مثال على التحقق الصحيح من البريد الإلكتروني:

\n\n
<?php\n$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);\nif ($email === false) {\n    // البريد الإلكتروني غير صالح — لا نحفظه ولا نخرجه\n    echo "أدخل بريدًا إلكترونيًا صحيحًا";\n    exit;\n}\n// الآن $email سلسلة آمنة لأي غرض\n?>
\n\n

القاعدة الذهبية: إذا كنت تتوقع رقمًا — تحقق من أنه رقم. إذا كان بريدًا إلكترونيًا — تحقق من التنسيق. كل ما عدا ذلك — ارفضه.

\n\n

الخطأ رقم 4: تجاهل سياق المخرجات (XSS)

\n\n

لقد حفظت البيانات في قاعدة البيانات باستخدام استعلامات محضرة. رائع، لا يوجد حقن SQL. لكن

المدونات

توصيات الكتب