مقدمة:
مع ظهور لغة الجافا رافق ظهورها تركيز كبير على موضوع الأمن، فقد أعلن عن الأمن كواحد من أهداف اللغة الرئيسة الواجب تحقيقها، و كان الطموح أن يكون الأمن هو ما سيميز لغة البرمجة جافا عن لغات البرمجة الأخرى، و مع انه من النادر أن تضم أي تقنية جديدة ميزات سرية عالية عند إصدارها الأول، ولكن مع ذلك فقد برزت لغة الجافا كأفضل منصة لبرمجة تطبيقات الانترنت الآمنة و قد جذب ذلك الكثير من الاهتمام من فريقي محترفي الأمن، ومصنعي الحواسب بشكل عام . و في غضون السنوات التالية انهمر الباحثون و الأكاديميون و الطلاب على تفاصيل تصميم و الشفرة المصدرية ل SDK و التي أصدرتها شركة Sun Microsystems،حتى أن كبريات الصحف العالمية الشهيرة مثل مجلة وول ستريت وجريدة نيويورك تايمز قامتا بتغطية الموضوع بشكل واضح.
من وجهة نظر مبدعي جافا فهم يرون أن الأمن في جافا يؤمن ميزتين رئيستين:
• منصة جافا قبل كل شيء هي منصة آمنة بحيث يتم تشغيل تطبيقات جافا بطريقة آمنة .
• يوجد العديد من أدوات و خدمات الأمن ضمن لغة البرمجة الجافا و التي تؤمن مجالا واسعا من تطبيقات الأمن .
إن انتشار تقنية الجافا زاد أيضا من انتشار قضايا الأمن المهمة. تركز هذه المقالة بشكل رئيسي على الميزات الأساسية في الأمن التي تؤمنها منصة و لغة البرمجة جافا .
منصة و لغة البرمجة جافا :
تم تصميم لغة البرمجة جافا بالأصل للاستخدام في التطبيقات الاكترونية المضمنة مثل الأجهزة الكفية، وتعتبر لغة الجافا لغة غرضية التوجه بشكل عام، و هي بسيطة كفاية بحيث يتآلف معها المبرمجون بسرعة. صممت هذه اللغة لتكون منصة مستقلة بحيث أن مطوري التطبيقات يمكنهم كتابة تطبيقهم مرة واحدة و من ثم تنفيذه بأمان أينما شاءوا على الانترنت، كما أن لغة الجافا متعلقة بلغة C و لغة C++ و لكنها مختلفة عنها فقد حذفت بعض المفاهيم من لغة C و لغة C++ كما استعانت لغة الجافا بأفكار من لغات البرمجة الأخرى الموجودة .
بعد هذه المقدمة السريعة دعونا ندخل في موضوع الأمن، إن أولى مبادئ الأمن في جافا أنها لا تسمح لك بتضمين أي بواني غير آمنة، إذ أن بعض البواني الغير آمنة قد تسبب سلوكا للبرامج لا يمكن التنبؤ به، وعلى سبيل المثال لا يتم السماح بالوصول لمصفوفة ما دون التأكد من دليلها، تأتي لغة الجافا مع نظام إدارة تخزين أوتوماتيكي، وعادة ما يتم ذلك بواسطة مجمع المهملات garbage collector و بالإضافة لما سبق تتجنب لغة الجافا قضايا الأمان المتعلقة بالذاكرة مثل تلك التي تحدث في لغة C بواسطة free و لغة C++ بواسطة delete إذ تقل درجة الصعوبة عند التعامل مع الذاكرة بعكس ما هو الحال مع اللغات الأخرى .
يتم ترجمة البرنامج المكتوب بلغة البرمجة جافا أي ما يدعى برنامج جافا Java Application إلى بنية تدعى البايت كود bytecode و من ثم إلى بنية ملف ثنائي binary بحيث يتم فهمه بواسطة آلة جافا الافتراضية JVM وتعرف لغة الجافا أيضا عدد من الحزم من اجل دعم البرمجة بشكل كامل.يتم تخزين برامج الجافا كملفات ثنائية تمثل الصفوف و الواجهات المترجمة.
يتم تحميل ملفات الصف الثنائية إلى آلة جافا الافتراضية JVM ومن ثم يتم ربطها معا و تهيئتها و تنفيذها و فيما يلي مثال على برنامج بسيط :
class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.print(i == 0 ? args[i] : " " + args[i]);
System.out.println();
}
}
إن الصف Test الذي تم تخزينه في الملف test.java يمكن أن يتم ترجمته و تنفيذه بواسطة الأوامر التالية:
javac Test.java
java Test Hello
إن البرنامج السابق سيقوم بطباعة Hello .
كما ذكرنا سابقا ترتكز لغة الجافا على الشبكات بالأساس، و قد صنعت بالأصل لتنفيذ فكرة أن برنامجا ما يمكن أن يعمل على عدة أنواع من الحواسب و آلات مختلفة مثل الأجهزة الكفية، وأجهزة الموبايل، والعديد من الأجهزة الأخرى.إذا يمكنك بواسطة تقنية جافا استخدام نفس التطبيق تحت منصة عمل تستخدم نظام التشغيل Windows ، و تحت منصة عمل أخرى تستخدم Linux ، أو حتى نظام التشغيل Solaris. لعل أحد الأمثلة على قوة منصة جافا مستعرض HotJava حيث يقدم إمكانية تضمين برامج الجافا ضمن صفحات الانترنت HTML ، و تدعى هذه البرامج بالبريمجات Applets و يمكن تحميلها بشفافية بحيث تعمل و تشغل داخل المستعرض. تم دمج منصة جافا بشكل متكامل إلى معظم مستعرضات الويب الشائعة في وقتنا الحاضر ، كما أن تقنية الجافا تم دمجها و تضمينها في البطاقات الذكية , بطاقات الهواتف , مشغلات الألعاب و بذلك لا حاجة لبرامج الجافا للاعتماد على المستعرض .
تتألف منصة جافا من لغة البرمجة جافا و آلة جافا الظاهرية بالإضافة لواجهات برمجة التطبيقات أو ما يدعى مكاتب API . تعتبر آلة جافا الافتراضية مجرد آلة حسابية فقط لا تفترض أي وجود أي تقنية معينة أو منصة خاصة و لا تعرف هذه الآلة أي شيء عن لغة البرمجة جافا، و عوضا عن ذلك فهي تفهم فقط صيغة معينة من الملفات هي صيغة ملف الصف class file format حيث يحتوي ملف الصف class file على تعليمات آلة جافا الافتراضية أو ما يدعى البايت كود bytecodes بالإضافة لجدول الرموز وبالإضافة لمعلومات إضافية . يمكن تفسير البايت كود أو ترجمته لأي منصة بشكل عام و يمكن تحقيق آلية جافا الافتراضية إما بواسطة المايكرو كود microcode أو مباشرة بشكل هاردويري .
الهيكلية الأساسية للأمن في جافا :
في الإصدار الأول لمنصة جافا تركزت هيكلية الأمن على السماح للمستخدم باستيراد و تشغيل بريمجات الجافا بشكل ديناميكي بدون أية مخاطر على نظام المستخدم . عادة ما يكون البريمجapplet عبارة عن أي شفرة برمجية حرة لا تتعلق بالنظام المحلي، ويجب أن يتم تحميله قبل تشغيله أما الشفرة التي توجد على النظام المحلي فتدعى بتطبيق جافا Java application و يدعى ذلك أيضا بالتطبيقات المعتمدة على تقنية جافا، ولأنه يتم تحميل البريمجات بشكل ديناميكي، و غالبا ما يتم ذلك دون حذر و لأنك ربما لا تعرف من هو كاتب البريمج، لهذه الأسباب جميعا لا يمكنك الثقة بشكل أعمى بالبريمج بأنه موثوق و غير مؤذي، لذلك عادة ما تكون عمليات تحميل البريمجات مقيدة بما يسمى Sandbox و الذي هو عبارة عن جزء من مستعرض الويب مخصص للبريمجات، و بالتالي يعمل البريمج ضمن منطقته الخاصة به في المستعرض، و لا يمكنه الوصول أبعد منها. كمثال على ذلك لا يمكن للبريمج قراءة أو تعديل أي ملف موجود على نظام المستخدم، وفي تلك الحالة إذا قام المستخدم باستيراد بريمج معادي بالخطأ فإنه لن يؤذي نظامه و هكذا يؤمن موديل Sandbox بيئة تقييد قوية جدا عند تنفيذ الشفرات غير الموثوقة التي يمكن أن تصل للمستخدم نتيجة دخوله للشبكة .تم توظيف نموذج Sandbox من خلال أداة تطوير جافا JDK التي تتضمن مستعرضات الانترنت التي تقبل تقنية جافا.
كانت جميع التطبيقات في منصة جافا الأولى (و التي هي عكس البريمجات )موثوقة بشكل كامل، وبالتالي كانت تتمتع بإمكانيات كاملة للوصول لموارد النظام كملف نظام مثلا. يأتي الأمن من خلال المحافظة على التحكم الفيزيائي ضمن الأنظمة، و كمثال على ذلك منع المستخدمين من تنصيب البرمجيات الغير آمنة و التي قد تكون مؤذية. يمكنك ملاحظة أن الاختلاف بين البريمج و التطبيق ليس مطلقا فهما ليسا متضادان دوما، فإذا كان لديك نظام ملفات شبكي و بقي ملف الصف في نظام الملفات المحلي فإنه ربما في الواقع يتوضع على بعد آلاف الأميال بعيدا عنك بينما البريمج الذي يمكن تحميله من شبكة محلية LAN يمكن أن يكون من نفس المضيف الذي يعمل عليه المستخدم .
تتضمن الهيكلية الأساسية في الأمن عدداً من الآليات :
• أولا: صممت لغة البرمجة جافا بحيث تكون آمنة و سهلة الاستخدام و بذلك يكون المبرمج أقل عرضة للوقوع في أخطاء بالمقارنة مع تلك الإمكانيات المتاحة من قبل لغات برمجة أخرى مثل لغة C أو لغة C++ . إن إدارة الذاكرة الآلية أو ما يسمى بمجمع المهملات و الفحص الآلي للنصوص Strings و المصفوفات هي بعض الأمثلة عن كيفية مساعدة جافا للمبرمج لكتابة شفرات برمجية آمنة و صحيحة .
• ثانيا: يقوم مدقق البايت كود بالتأكد من أنه يتم تنفيذ الشفرة الصحيحة المكتوبة بلغة البرمجة جافا، أن المترجم Compiler يقوم بترجمة برامج الجافا إلى تمثيل مستقل عن الآلة يدعى بالبايت كود و قبل تشغيل بريمج ما تم تحميله حديثا يقوم مدقق البايت كود بالتأكد أن البريمج يخضع لمواصفات لغة البرمجة جافا، وأنه ليس هناك خرق لقواعد لغة البرمجة جافا، أو أن هناك قيود تتعلق بالاسم مثلا، و هذا هو هدف الأمن، تفرض لغة الجافا الافتراضية قيودا قوية على الشفرات البرمجية في ملف الصف يقوم المدقق أيضا بفحص خروقات إدارة الذاكرة، تدفقات المكدس الزائدة و أنواع المعطيات غير النظامية. إن عملية التدقيق ضرورية جدا فبدونها يمكن لبريمج مؤذي أن يسبب الضرر لجزء من آلية الأمن المتبعة أو استبدال جزء من النظام بشفرة أخرى من عنده . و هكذا فقد تم تصميم مدقق البايت كود مع آلة جافا الظاهرية JVM سوية لضمان أمان اللغة وقت التنفيذ، و للتأكد من أمان الأنواع بشكل كامل تستخدم آلة جافا الظاهرية فحص للأنواع وقت التنفيذ عند تخزين المرجعيات في المصفوفات. تتضمن فعاليات وقت التنفيذ تحميل و ربط الصفوف اللازمة للتنفيذ و أحيانا من أجل توليد شفرة الآلة و تنفيذ البرامج، و خلال هذه العملية يقوم محمل الصف بتعريف أسماء محلية بحيث يتم استخدامها للتأكد من الشفرات غير الموثوقة التي لا يمكن أن تتضارب مع تشغيل برامج جافا الأخرى .
• ثالثا : يتم الوصول لموارد النظام الهامة الحساسة عبر آلة جافا الظاهرية JVM و يتم فحصه أيضا بواسطة صف مدير الأمن الذي يقوم بتقييده إلى حدوده الدنيا عند استخدام شفرة برمجية غير موثوقة
أمان النوع التأكد من البايت كود :
على الرغم من أن المترجم يقوم بالتأكد أن الشفرة المصدرية المكتوبة بلغة البرمجة جافا لا تخرق قواعد الأمن و لكن مع ذلك يمكن لشخص ما أن يتلاعب بالمترجم لتوليد شفرة مؤذية، و قد لا يكتشف المترجم أنها تخرق قواعد الأمن .
إن مستعرضات الويب التي تقبل تقنية جافا و التي يمكنها استيراد أجزاء من الشفرة من أي مكان لا يمكنها معرفة أي جزء من الشفرة جاء من مترجم موثوق. و هكذا قبل تنفيذ أي جزء من الشفرة يقوم النظام وقت التنفيذ بإخضاعها لسلسلة من الاختبارات .
تتنوع هذه الاختبارات ما بين التأكد أن صيغة هذا الجزء من الشفرة صحيحة ليتم بعد ذلك تمريرها إلى مدقق بسيط للتأكد أن الشفرة تحقق قواعد الأمن، و يمكن القول أن الشفرة يتم فحصها للتأكد من الأمور التالية :
• لا تحتوي تحويلات معطيات غير نظامية، مثل تحويل نمط معطيات من النوع الصحيح Integer إلى مؤشرات Pointers .
• لا تحتوي مؤشرات مزيفة، وتجدر الملاحظة هنا أن لغة الجافا لا تحتوي نمط المؤشرات .
• لا تخرق قيود الوصول، و كمثال على ذلك يجب أن لا يكون الحقل الخاص Private ممكن الوصول من خارج الغرض .
• يمكنها الوصول للأغراض كما تريد، و كمثال على ذلك تتأكد هذه الاختبارات من أغراض InputStream التي تستخدم دوما فقط كأغراض دخل InputStream و لا يمكن استخدامها لأي شيء آخر قط .
• تستدعي طرق بمتحولات مناسبة من أنماط مناسبة أيضا و لا يوجد تدفق زائد للمكدس stack overflows و تتأكد أن الطرق تقوم بإعادة أغراض من النوع المناسب أيضا.
هنا يمكنك ملاحظة أن مدقق البايت كود ليس مطلوبا بقوة للتأكد من أمان النوع type safety و ذلك لأن آلة جافا الظاهرية يمكنها نظريا إنجاز فحص النوع بشكل كامل خلال وقت التنفيذ، و على كل حال غاليا ما يسبب الفحص وقت التنفيذ إبطاء تنفيذ البرامج بشكل ملحوظ لأن مثل هذه الفحوصات يجب أن تتم بشكل متكرر عند استدعاء كل طريقة، و بذلك فإن نقل بعض الفحوصات لحين تحميل الصف حيث تحدث هذه الفحوصات مرة واحدة فقط يمكن اعتباره استراتيجية مغرية. إن معرفة أن شفرة ما تم تحميلها تتوافق مع هذه الخواص، يجعل من نظام وقت التنفيذ يعمل بشكل أسرع لأنه لا يحتاج لفحصهم و يمكنك ملاحظة أن المدقق مستقل عن لغة البرمجة جافا، و عن المترجم أيضا، و بالتالي يمكنه أيضا فحص البايت الكود الذي يتم توليده من شفرات مصدرية للغات برمجة أخرى إضافة للغة البرمجة جافا .
لا يمكن اعتبار الفحوصات الخمسة المذكورة سابقا كاملة أو نظامية و لا تعتبر دقيقة و تحتوي بعض القصور .و لتجاوز ذلك إنه لفعال أن نفهم النقاط التالية :
إن الهدف الرئيسي لهيكلية الأمن في جافا هو التأكد من أن تخصيصات لغة البرمجة جافا، و تخصيصات آلة جافا الظاهرية هي مراقبة و منفذة بشكل صحيح، ولفهم ذلك بشكل أكبر تخيل أنك تقوم بكتابة تطبيق مفكرة ما Calendar عندئذ سيكون لديك واجهات تتوقع أن تحصل على قيمة بين 1 و 12 لتمثيل شهر ما ضمن السنة، و يمكنك أيضا أن تكتب واجهة تهيئة تقوم بأمر المستخدم بإدخال الشهر الحالي، و لأن واجهاتك الأخرى تفترض أن رقم الشهر الصحيح هو بين 1 و 12 إنه لمن الحكمة أن تفحص و تتأكد من خلال إجراء التهيئة الداخلي من أن الدخل هو عدد مقبول، و قد لا يعمل تطبيق المفكرة بسبب إدخال رقم خارج المجال 1- 12 و يتصرف البرنامج بطريقة غريبة نتيجة ذلك .
يطبق مبدأ شبيه بما سبق في منصة جافا، حيث أن آلة جافا الظاهرية تتوقع البايت كود الذي تشغله للحصول على خواص محددة، و إنها وظيفة مدقق البايت كود أن يقوم بالتأكد من تقابل هذه الخواص و وجودها. كذلك الحال تقوم آلة جافا الظاهرية بفحص الخواص الإضافية بنفسها، و هي تقوم بذلك لان هذا الأمر صعب على مدقق البايت كود ليقوم به.
ربما أنك تتساءل الآن ما هي سلامة النوع الذي يجب القيام بها لتحقيق أمن الحاسب . إن سلامة النوع تساهم في تحقيق صحة البرامج، فإذا كان لديك برنامج ما يحقق وظائف الأمن، و لم يحقق ما هو مطلوب منه لان البرنامج لم ينفذ بشكل صحيح فإن وظائف الأمن قد لا تطبق بشكل صحيح و كمثال على ذلك يمكن تصوير الأمن في اختبار مساواة على الشكل التالي :
if (name.equalsIgnoreCase("Chuck Jones")) {
openDoorToHackersLounge()
} else {
throwThemOut()
}
هنا تم كتابة فكرة الأمن و تم إنجازها بواسطة لغة البرمجة جافا و حيث الشفرة السابقة توضح بأن جواب نعم غير ممكن فيما إذا نصاً مثل "ChuckJones"تم مقارنته بنص آخر مختلف مثل "Tex Avery" و بالتالي إنه لمن الضروري ملاحظة أن كل مشاكل سلامة النوع لها نتيجة حتمية هي حصول خرق للأمن، و كمثال إذا كان تحقيق implement الآلة الظاهرية JVM يحتوي على خطأ صغير بحيث يؤدي أن يتساوى النص "acegikmoqsuwy" مع النص "bdfhjlnprtvxz"عندها يمكنك تخيل الثغرة الأمنية الناتجة بالخلاصة سلامة النوع تقتضي اهتماما بالغا و لا يمكن تركها للحظ .
البريمجات الموقعة Signed Applet :
جاء مفهوم البريمج الموقع مع الإصدار JDK 1.1و بالعودة إلى نموذج Sandbox الذي تكلمنا عنه سابقا إن كل الشفرات البعيدة و نقصد هنا البريمجات هي غير موثوقة، و مقيدة بالعمل فقط ضمن Sandbox و هذه القيود على الرغم من كونها تساهم ببيئة حساب آمنة، و لكنها مقيدة جدا . ضمن شبكة على سبيل المثال يمكن لشركة ما توظيف بريمج بحيث يستخدم للمحافظة على معطيات موظف ما، إن الموظف الذي قام بتحميل و تشغيل البريمج لتغيير معطيات ما يريد أن يقوم البريمج بتحديث سجلاته مباشرة بعد التعديل .
و لتسهيل مثل ذلك أضافت JDK 1.1 دعما للتوقيع الرقمي بحيث أن ملفات صفوف البريمجات بعد إنشائها يمكن أن يتم توقيعها و تخزينها معا مع توقيعها بصيغة مضغوطة، و هي صيغة أرشيف جافا JAR و من أجل كل تنصيب ل JDK يمكنك تحديد من هو الموقع أي الذي قام بالتوقيع و يكون ذلك بتخصيص مفاتيح عامة Public Keys موثوقة، وعندما يتم تحميل بريمج موقع رقميا بشكل صحيح يمكن لمن قام بتوقيعه التأكد منه أنه موثوق، وعندها يتم التعامل مع البريمج على أنه موثوق و يحصل على وصول كامل للنظام