أمان جافا: كيفية حماية الكود من هجمات SQL Injection و XSS

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

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

ابدأ الدورة

كيف تمنع المخترقين من اختراق كود جافا الخاص بك: SQL Injection و XSS تحت المجهر

\n\n

تخيل: لقد كتبت تطبيق ويب مثاليًا بلغة جافا. واجهة جميلة، منطق سريع، بنية نظيفة. تقوم بنشره على الخادم، وتُحضر كوب شاي... وبعد ساعة تتلقى رسالة تفيد بأن قاعدة البيانات قد حُذفت، وعلى الصفحة الرئيسية يظهر رسم ASCII استفزازي لشخص ما. قصة مألوفة؟ للأسف، بالنسبة للعديد من المطورين — نعم.

\n\n

أكثر ثغرات تطبيقات الويب شيوعًا وخطورة — SQL Injection و Cross-Site Scripting (XSS) — تحرم مسؤولي آلاف المواقع من النوم سنويًا. وجافا، على الرغم من صرامتها، ليست استثناءً. لكن هناك خبر سار: الحماية منها ممكنة. بل وليست صعبة جدًا.

\n\n

في هذه المقالة، سنشرح كيف يهاجم المخترقون تطبيقات جافا، والأهم من ذلك — كيفية إنشاء حاجز موثوق باستخدام أدوات مثبتة وعادات برمجة صحيحة. اربطوا أحزمة الأمان: سيكون هناك الكثير من الأكواد والحيل العملية والحد الأدنى من الحشو.

\n\n

SQL Injection: عندما يصبح المستخدم مبرمجًا

\n\n

ما هو ولماذا يعمل؟

\n\n

SQL Injection هي تقنية هجوم يقوم فيها المخترق بـ"حقن" كود SQL ضار في الاستعلام عبر إدخال المستخدم. إذا كان التطبيق يدمج السلاسل النصية بلا وعي، يمكن للمهاجم الوصول إلى بيانات الآخرين، أو حذف الجداول، أو حتى السيطرة على خادم قاعدة البيانات.

\n\n

مثال كلاسيكي لكود سيء في جافا:

\n\n
String userInput = request.getParameter("username");\nString query = "SELECT * FROM users WHERE username = '" + userInput + "'";\nStatement stmt = connection.createStatement();\nResultSet rs = stmt.executeQuery(query);
\n\n

ماذا يحدث إذا أدخل المستخدم: admin' OR '1'='1؟ يتحول الاستعلام إلى:

\n\n
SELECT * FROM users WHERE username = 'admin' OR '1'='1'
\n\n

الشرط '1'='1' صحيح دائمًا. تهانينا: لقد دخل المخترق للتو إلى النظام كمسؤول، حتى دون معرفة كلمة المرور. وإذا أدخل '; DROP TABLE users; -- — فقد انتهى كل شيء.

\n\n

كيف تحمي نفسك: PreparedStatement — درعك

\n\n

القاعدة الأولى في أمان تطبيقات جافا: لا تقم أبدًا بدمج بيانات المستخدم مع استعلامات SQL. استخدم الاستعلامات المُعلمة عبر PreparedStatement.

\n\n

هذا هو الشكل الذي يجب أن يبدو عليه الكود الآمن:

\n\n
String userInput = request.getParameter("username");\nString query = "SELECT * FROM users WHERE username = ?";\nPreparedStatement pstmt = connection.prepareStatement(query);\npstmt.setString(1, userInput);\nResultSet rs = pstmt.executeQuery();
\n\n

ماذا حدث هنا؟ تتلقى قاعدة البيانات الاستعلام والبيانات بشكل منفصل. حتى إذا كان userInput يحتوي على كود SQL ضار، فسيتم التعامل معه كسلسلة نصية عادية، وليس كأمر. يقوم PreparedStatement تلقائيًا بترميز الأحرف الخاصة. هذا هو خط الدفاع الأول والأهم.

\n\n

إجراءات إضافية: الإجراءات المخزنة والتحقق من الصحة

\n\n

بالإضافة إلى PreparedStatement، يُنصح باستخدام:

\n\n
    \n
  • الإجراءات المخزنة — استدعاء الإجراء عبر CallableStatement يفصل أيضًا الكود عن البيانات.
  • \n
  • القوائم البيضاء — إذا كنت بحاجة إلى إدراج اسم جدول أو عمود (وهو أمر نادر)، فلا تأخذه أبدًا من إدخال المستخدم. استخدم enum أو ثوابت محددة بدقة.
  • \n
  • التحقق من صحة الإدخال — تحقق من أن البريد الإلكتروني يشبه البريد الإلكتروني بالفعل، وأن الرقم هو رقم. لكن تذكر: التحقق من الصحة هو طبقة إضافية، وليس بديلاً عن PreparedStatement.
  • \n
\n\n

مثال للعمل الآمن مع أسماء الجداول الديناميكية:

\n\n
public enum TableName {\n    USERS, PRODUCTS, ORDERS\n}\n\npublic void queryTable(TableName table) {\n    String que                

المدونات

توصيات الكتب