التواصل مع الدعم

نردّ عبر البريد الإلكتروني، عادةً خلال يومين.

يفحص Google reCAPTCHA هذا الإرسال للحماية من إساءة الاستخدام؛ وتُرسَل بيانات إلى Google. لا يُحمَّل السكربت إلا عند فتح هذا النموذج.

→ كل المقالات

ما الذي يطاله حذف العداد فعلًا

حذف عداد هنا يُفرغ 33 جدولًا. وبالأمس كان يُفرغ 25.

والجداول الثمانية التي فاتته أُنشئت كلها في اليوم السابق، بين 11:10 صباحًا و15:10 بعد الظهر.

33 جدولًا تحتفظ بشيء عن العداد 8 منها لم تكن تُفرغ — وكلها أُنشئت في اليوم السابق كان في هذه الثمانية معًا 4,840 صفًا أُضيفت اليوم في موضعها الأبجدي، لا في نهاية القائمة 25 صفًا يتيمًا في جداول أخرى، عُثر عليها وأُزيلت

كيف يعمل الحذف

يستطيع صاحب العداد حذف عداده. ويتطلب ذلك طلب POST، ورمز صاحب العداد، ورقم العداد مكتوبًا باليد، لأنه لا تراجع. ولا يُحتفظ بأي شيء جانبًا: فالنسخة الظلية ستكون عكس ما طُلب، وروابط التصدير موجودة فوق الزر لمن يريد نسخة.

ثم تُفرغ قائمة من الجداول في معاملة واحدة، والجدول الرئيسي آخرها، ويُضاف شاهد قبر (tombstone) إلى الأرشيف كي لا يُمنح الرقم لشخص آخر أبدًا. وإذا فشل أي جزء، تُلغى العملية كلها. ألّا يُحذف شيء خير من أن يُحذف النصف.

وفوق تلك القائمة، في الملف، هذا التعليق:

«كل جدول يعرف شيئًا عن هذا العداد. في قائمة، لا مبعثرًا في الكود: فما ينقص هنا يبقى صفًا يتيمًا، ولا يلاحظه أحد.»

وصف التعليق الثغرة قبل أن تنفتح بيوم

بالأمس ظهرت ستة جداول جديدة لميزة جديدة — مدة البقاء في الصفحة، وعمق التمرير، وصفحات الخروج — ومعها جدولان آخران. بين 11:10 و15:10.

عُدّلت قائمة الحذف في اليوم نفسه لإضافة جدول جديد آخر. ووصلت الجداول الثمانية بعد ذلك، ولم تتغير القائمة مرة أخرى. وهكذا، طوال ظهيرة واحدة، كان حذف العداد يترك خلفه 4,840 صفًا من بيانات السلوك، موزعة على ثمانية جداول. اكتُشفت الثغرة في اليوم التالي وأُغلقت؛ وما كشفته هو أن القائمة كانت تحتاج إلى شيء غير الذاكرة لإبقائها كاملة.

ليست هذه قصة إهمال. أحدهم كتب القائمة، وفهم تمامًا لماذا هي قائمة، ودوّن ما يحدث حين تتأخر عن الواقع، وحدّثها في اليوم نفسه من أجل جدول واحد. ومع ذلك تأخرت، لأن إبقاء أمرين متوافقين بالاعتماد على التذكّر شيء يتقنه البشر حتى تأتي الظهيرة التي لا يتقنونه فيها.

الإصلاح، والإصلاح الآخر

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

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

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

ما يمكن تعميمه من ذلك

كل قائمة يجب أن تبقى متوافقة مع شيء آخر ستفقد هذا التوافق في النهاية، وستكون الثغرة غير مرئية، لأن القائمة التي ينقصها إدخال تبدو تمامًا مثل القائمة الكاملة.

والحل ليس الانضباط. بل استنتاج أحد الجانبين من الآخر والتحقق من تطابقهما — وإجراء هذا الفحص لحظة يضيف أحدهم الشيء، لا لحظة يتساءل أحدهم.

كان التعليق فوق القائمة محقًا في كل شيء إلا في كلمة واحدة. قال إن أحدًا لا يلاحظ. لكن أحدهم لاحظ، بعد يوم واحد، لأنه بحث بسكربت بدلًا من ذاكرته.

إعلان