إنه لأمر جيد أن يكون هناك شخص أكثر خبرة في الفريق الذي سيُظهر ماذا وكيف يفعل ، وما أشعل النار ، وزاوية ماذا ، وأين يمكن تنزيل أفضل رسومات الدراجات لعام 2007 على قرص DVD. تدور هذه القصة حول كيفية إعطاء الرغبة على أنها صحيحة ، وما تبين نتيجة لذلك ، وكيف تم التغلب على الأزمة.
لقد حدث هذا في وقت كنت أتطلع فيه إلى تجربة متواضعة في مجال التنمية ، حيث كنت أبحث عن مكان يمكنك من خلاله التطور (أو التغيير) من شخص غير مبتدئ إلى مستوى مبتدئ. في طرق غامضة للرب تم العثور على مثل هذا المكان ، تم إرفاق مشروع بالمكان ، ومبرمج "المدرسة القديمة" ، الذي كتب أكثر من الفتيات عن حياته المهنية في النظم. "! ممتاز المشروع ، وبالتالي هناك أموال لطلب تقديم العروض ، والمعلم مرتبط ، نحن نعيش! " فكرت ، لكن بعد ذلك ، كما في وصف الرعب المعتاد ، واجه الأبطال في الظلام الظلام رعبًا رهيبًا ...
أول الأشياء أولاً:
1. حجم المسائل
بدأنا التطوير على محرك php ذي ملكية فردية ، يستخدم لتخزين البيانات (هنا قد تظن MySQL \ PostgreSQL \ SQLite \ MongoDB \ Something-else-but-بالضرورة-with-لاحقة DB-خلاف ذلك- يا شباب ، فهم لا يفهمون ، لكنهم لم يخمنوا) بوابة api.
"هاها ، باستخدام php ، هل تقوم بتوصيل بوابة api أخرى بها ، وتخزين البيانات عليها؟ ليس من السهل التعامل مع api مباشرة من js-code؟ أو استخدام DBMS + PHP؟ " - اسأل القارئ المخضرم. وسوف يكون على حق. لكن في ذلك الوقت ، لم أكن أفكر في هذا الأمر ، من يدري ، من المحتمل أن الرجال اللطيفين يفعلون ذلك ، كما يعلم مبرمجو "المدرسة القديمة" بشكل أفضل.
كما أوضح لي أكثر:
- بوابة = الأمن ، لا أحد سيدخل والخروج تماما مثل ذلك
- Gateway = تخزين آمن للبيانات ، لا يمكنك الدخول إليه ، + نسخ احتياطية
- بوابة = السرعة ، يعمل بسرعة وبدون فشل ، اختبار الزمن
- وجهة نظر موثوقة من المبرمجين "المدرسة القديمة" هو أن php الخاص بك مليء بالثغرات ، يتم اختراق أي تطبيق ويب بشكل افتراضي ، لذلك لا يوجد شيء لتخزين البيانات بجانبه
كانت السمة المميزة لبوابة api هي إرسال بيانات json في طلب الحصول على. نعم ، نعم ، تم تعريض كائنات json الرائعة هذه إلى تشفير عنوان url ووضعها في سلسلة الاستعلام. وسيكون كل شيء على ما يرام ، عندما فجأة يوم واحد ... طول طلب الحصول على توقف عن أن يكون كافيا. بغباء ، فإن json-encloded ، kalalya ، لم يصلح هناك! سأل مبرمج المدرسة القديمة وهو يخدش رأسه:
"ماذا سنفعل؟ نمت لدينا json ، لكننا لم نلاحظ ... "
"حسنًا ، ربما ، ثم سننشرها في المنشور؟" اقترحت ، لذلك يبدو أنه أكثر صحة.
"حسنا ، مرر للنشر."
كان atas رقم واحد.
2. إدارة الوقت والنسخ الاحتياطي
لربط وظائف جديدة في المشروع ، كان من الضروري تنفيذها
طلبات CRUD المقابلة على البوابة ، وهذا بالضبط ما فعله رفيق "المدرسة القديمة" بالفعل. كانت المشكلة أنه فعل هذا مرة واحدة كل 3 أيام ، مع إعطاء "تم ، تحقق". أثبتت عمليات الفحص في بعض الأحيان أنه لا يعمل كل شيء ، على سبيل المثال ، الحصول على القائمة على ما يرام ، إضافة عنصر جديد ليس على ما يرام. استغرق الأمر بعض الوقت لإصلاح وتحسين ، وبعد ذلك كان من الممكن لإطلاق سراح وظيفة في الوصول الشامل. تم رفض الاقتراح الداعي إلى تنفيذ الاستعلامات على البوابة بنفسك ، لأنه أسرع على الأقل ، لأنه "من الصعب هناك ، فلن تكتشفها". وكانت نتيجة هذا النهج إغلاق العمل "على نفسي". على سبيل المثال ، إذا كان من الضروري إصلاح شيء ما بشكل جماعي في قاعدة البيانات ، إذن ، فاختر بين الانتظار لمدة 3 أيام وتنفيذ التصحيحات بنفسي من خلال الاستعلامات - لقد اخترت الخيار الثاني. العملاء لا يحبون الانتظار بشكل خاص ، طار التمهيدية الجديدة بثبات. أحد هذه الاستهلالي ، وهو وضع علامة جماعية على مستخدمي علامة ما ، أوكلت إليّ تنفيذ ، كان هناك ساعة لكل شيء عن كل شيء ، كانت السلطات تنتظر تقريراً جميلاً. هنا ينتظرنا أتاس رقم اثنين.
والحقيقة هي أن تنسيق بيانات json المرسلة في الطلبات لا يتضمن سوى عدد قليل من الحقول المطلوبة ، وجميع الحقول الأخرى كانت تعسفية ، ولم يكن هناك بنية واضحة ونهائية. على سبيل المثال ، لإضافة مستخدم ، مررتُ json بالنموذج:
POST /api/users { "email":"ivanov@mail.ru", "password":"myEmailIsVeryBig", "name_last":"", "name_first":"", "name_middle":"", "birth":"01.01.1961", // , - "living_at":"., .3 .4 .24", "phone_num":"+70000000000" }
تم حفظ الجزء الاختياري الذي تم إرساله في طلبات الإضافة / التحديث وتم تقديمه بالكامل (سأخبرك عن كيفية تنفيذ ذلك أدناه). خلاصة القول هي أن الوقت لا يقف ساكنا ، سيكون من الضروري حل المشكلة - لتحديث المستخدمين ، ووضع علاماتهم. ولكن لا تدفع الهيكل كله في كل مرة؟ يجب أن تحقق! لقد اختبرت ذلك بنفسي - لقد نقلت حقلًا واحدًا فقط في طلب التحديث ، وتم التحقق منه ، وظهر الحقل ، وبقية البيانات في مكانها الصحيح. النقطة صغيرة - حلقة وتحديث الباقي.
البرنامج النصي منتفخ بهدوء ، استقبال ونقل البيانات ، ويبدو أن كل شيء يسير على ما يرام ... عندما فجأة - مكالمة. "لا نرى اسم المستخدمين في النظام!" - تقرير من تلك النهاية من السلك. "تعال! حسنا لقد نجحت! - ركض البرد غير سارة عبر ظهري. أظهر مزيد من التحقيق أنه في الواقع ، تم الإشارة إلى الاسم "" في الاسم ، على الرغم من أن جميع البيانات الأخرى كانت موجودة. ماذا تفعل في مثل هذه الحالة؟ نشر النسخ الاحتياطي!
مبرمج "الرفيق" في المدرسة القديمة ، وأيضًا يا مشاكل! تحتاج النسخ الاحتياطي! متى يتم آخر ما تم عمله؟ " - اسال.
"اه ... سأرى الآن .... لا ، ليس هناك باكابا ".
تم حفظ الموقف بحقيقة أنه قبل ساعتين من الانتهاء من واختبار الوحدة النمطية مع التقارير ، كان لدي صندوق بتنسيق CSV يحتوي على جميع البيانات اللازمة ، وتم استعادة الطلب خلال ساعة أخرى.
الافتقار إلى الوثائق الواضحة ، وأوصاف خوارزميات العمل ، وفحص صحة المدخلات ، والأهم من ذلك - النسخ الاحتياطي لقواعد البيانات - atas number-s.
منذ ذلك الحين ، بدأت النسخ الاحتياطية لإزالة كل يوم.
3. ضرب عميق
متزعزع ، ولكن كان العمل يتحرك ، تم حل المشكلات ، بعضها أسرع ، وأبطأ ، وعندما فجأة ... أدرك العملاء أن النظام لم يفهم من خوادم شخص آخر ، ولهذا الموقف تجاه PD وتنظيم أنشطة ZI في ISPD انهم لن ضربة في الرأس. من الضروري نقل الخادم إلى نفسك.
لماذا لم يتم نقل النظام في الأصل؟ كان لدى القيادة شغف واحد - المركزية. الإدارة تحلم بنظام من شأنه أن يفعل كل شيء! هل تحتاج إلى إرفاق طفل إلى المدرسة؟ تذهب إلى النظام ، في مكتب خاص ، هناك ترسل طلبًا. تحتاج ، على سبيل المثال ، طلب البيتزا - تذهب إلى النظام ، إلى مكتب خاص آخر ، تقدم بطلب للحصول على البيتزا. ربما كنت ترغب في التواصل مع السيدات / السادة جميلة؟ يوجد في خدمتك خزانة خاصة ثالثة - فأنت أيضًا ترسل طلبًا إلى هناك وما إلى ذلك.
المزايا - يتم تسجيل الدخول وكلمة المرور لكل شيء ، ويتم تخزين البيانات بأمان وأمان على البوابة. هناك حتى النسخ الاحتياطية. و ، مانع لك ، لن يأخذ أحد منا هذا النظام! وحتى لو كان يأخذها بعيدا - ماذا بعد؟ ومع ذلك ، فهم لا يفهمون نظام الحماية ضد مبرمجي "المدرسة القديمة" - كل شيء معقد هناك.
تم إلغاء تحميل VDS مع النظام ، ونسب إلى العملاء ، ونشروه ، والجميع يرقص ويغني ، والجمال!
ثم غمرتني موجة من الفضول وبعض الشكوك.
إذا كان تطبيق الويب الخاص بنا ممتلئًا بالثغرات ، فأين البيانات؟ هل بقيت حقا على خوادم أخرى؟ وإذا قرروا إغلاق النظام من الخارج ، فهل سينهار كل شيء؟
أظهر فحص بسيط أن البيانات ، وكذلك معالجات البوابة نفسها ، كانت على نفس الخادم. ولا ، لم يتم نقلهم إلى هناك بسبب نقل الخادم ، لقد كانوا دائمًا هناك.
الآن أصبحت تحت تصرفي تطور "المدرسة القديمة" السري للغاية ، والذي وضعته حول البحث. بالطبع ، لم تنجح الهندسة العكسية في أسلوب مقالات مجلة Hacker ، مع ollydbg ، والإزاحة ، وغيرها من الأشياء الرائعة ، لذلك أشارك ما لدي.
تم تنفيذ التطوير نفسه في بيثون ، وكان هناك فقط ملفات .pyc التي يمكن فك ترجمتها بسهولة إلى كود قابل للقراءة. بصراحة ، استغرق الأمر الكثير من الوقت ، حتى 25 دقيقة ، لمعرفة كيفية عمله.
لذلك ، فإن النظام المعقد الذي طوره مبرمج "المدرسة القديمة" ، والذي لا يمكن فهمه سوى القليل ، يتكون من:
- البرنامج النصي معالجتها من قبل اباتشي ، الذي تلقى فعلا الطلب. ماذا فعل هذا السيناريو؟ تم فتح اتصال بمنفذ مضيف محلي معين وتمرير طلب هناك بكل بياناته. هذا كل شيء. الاهتمامات تذهب أبعد من ذلك.
- جزء الخادم الذي عالج الطلبات من البرنامج النصي. كان منطق أفعاله مثيرة للاهتمام للغاية. أولاً ، لا توجد معالجة للبيانات في التعليمات البرمجية ، ولا توجد استعلامات في قاعدة البيانات ؛ بدلاً من ذلك ، تم استدعاء وظائف قاعدة البيانات في PL \ SQL. كل المنطق ، والتحققات ، وهلم جرا ، وضعت كل شيء في وظيفة قاعدة البيانات. كان 50٪ من البرنامج النصي عبارة عن قاموس يحتوي على اسم الطلب ، والوظيفة المرتبطة به ، وأسماء معلمات الوظيفة التي يجب أن تتوافق مع البيانات التي تم تمريرها في سطر get-request. تم تمرير بيانات JSON ، إذا لزم الأمر ، كمعلمة منفصلة. كانت إحدى ميزات تنظيم جزء الخادم هي اتصال النسخ الاحتياطي أثناء مصادقة المستخدم. إذا تم العثور على تسجيل الدخول وكلمة المرور في قاعدة البيانات ، تم إنشاء معرف الجلسة ، وتم طي مثيل الاتصال المفتوح في القاموس (وتم قتله في غضون 10 دقائق حتى لا يتم قتله - كانت هناك طريقة خاصة لإطالة عمر الجلسة) ، كان المفتاح هو معرف الجلسة ، والذي هو مباشر في قاعدة البيانات غير مخزنة. ما مدى ارتباط معرّف الجلسة ببيانات المستخدم بالضبط؟ بعد كل شيء ، هل هناك طلب للبيانات التي لا يتم نقل معرف المستخدم؟ إنه يعمل ، مما يعني أن هناك خطأ ما هنا.
أعطيت تنمية صعبة للغاية للوعي بصعوبة ولم يكن في عجلة من أمره لكشف الأسرار المفقودة منذ فترة طويلة من سادة الماضي.
لا يصدق (انتقل إلى> التعريف ، بفضل PhpStorm لفهم PL \ SQL) ، غير المفهوم لعقل المواطن العادي الذي يعاني مع ذلك ، تم اكتساب المعرفة الحقيقية للحضارة المفقودة لمبرمجي المدارس القديمة. بشكل عام ، عند الاتصال ، تم إنشاء جدول مؤقت في وظيفة التحقق من بيانات المصادقة ، حيث تم تخزين معرف المستخدم.
كانت هذه مجرد البداية ، قائمة إرشادية بأوجه الضعف الخطيرة الموجودة:
- استخدام DDoS باستخدام مصادقة جماعية (كانت الاتصالات محجوزة ، وبالتالي ، استندت إلى حد اتصال DBMS ، والذي ، بالنظر إلى إمكانية تمديد فترة حياة الجلسة ، أتاح ملء الذاكرة تمامًا بالاتصالات ، وسيكون عمل المستخدمين الجدد في النظام مستحيلًا) ؛
- عدم وجود حماية ضد القوة الغاشمة (لم يتم اكتشاف عدد محاولات تسجيل الدخول الفاشلة ، لم يتم تخزينه ، لم يتم التحقق منه ؛
- عدم التحكم في الإجراءات مع الكيانات (على سبيل المثال ، تم إصدار قائمة المستندات التي طلبها المستخدم مع مراعاة المؤسسة التي يرتبط بها المستخدم ، وإذا كنت تعرف هوية المستند ، فيمكنك تنفيذ طلب تحديث / حذف المستند بنجاح ، وقائمة المستخدمين جيدة حتى بدون كلمات المرور ، التي ، بالمناسبة ، تم تخزينها في قاعدة البيانات في واضحة ، دون تجزئة ، يمكن أن يستقبلها أي شخص على الإطلاق).
والمشكلة الخطيرة الأخرى ليست نظام تخزين بيانات رسمي. كما وعدنا سابقًا ، أتحدث عن تخزين "أي حقول" من JSON. لا ، لم يتم تخزينها كصف في الجدول. تم تقسيمها إلى أزواج ذات قيمة رئيسية وتخزينها في جدول منفصل. على سبيل المثال ، بالنسبة إلى المستخدمين ، كان هناك جدولان - المستخدمون ، و user_data (مفتاح السلسلة ، قيمة السلسلة) - حيث تم تخزين البيانات بالفعل. وكانت نتيجة هذا النهج زيادة في الوقت مع عينات معقدة من قاعدة البيانات.
في الواقع كان هذا كافيا لاتخاذ وتنفيذ قرار نقل النظام إلى واجهة برمجة تطبيقات جديدة ومفهومة وموثقة ومدعومة.
أخلاقية
ربما يكون هذا النظام "Legacy" ، ومبرمج "المدرسة القديمة" الذي أنشأه هو جوهر Legacy.
ومع ذلك ، فإن الاستنتاجات هي كما يلي:
- إذا قيل لك "هناك أمر صعب ، فلن تفهم" - فهذا يعني أن هناك atas كاملة
- إذا تم سحقهم بالسلطة ، فهناك شيء نجس
- ثق ، ولكن تحقق - الأمان ليس حالة ، والأمن هو عملية ، علاوة على ذلك مستمر ، لذا فمن الأفضل التأكد من أن الصفات المعلنة صحيحة من أن تكتشف فيما بعد أن جميع المستخدمين أصبحوا فجأة "إيفانوف إيفانوف إيفانيتش" ، ولكن لا توجد قيود.