انكشاف البيانات الحساسة

انكشاف البيانات الحساسة (Sensitive Data Exposure) هو العيب الذي تصبح فيه بيانات يُفترض أن تبقى خاصة مقروءةً لمن لا يحق له رؤيتها: رمز جلسة في رابط، أو رقم الهوية الوطنية لعميل في استجابة API، أو رقم بطاقة في ملف سجلات، أو تتبّع المكدس (Stack Trace) في صفحة خطأ. لا أحد يقتحم النظام؛ فالتطبيق نفسه يسلّم البيانات، وكل نسخة منها — في سجل المتصفح وسجلات الوصول ولقطات الشاشة وترويسة Referer — تسافر أبعد مما خطط له أحد.

جاء الاسم من إصدارات أقدم من قائمة OWASP Top 10. ومنذ إصدار 2021 تسمّي القائمة الأسباب الجذرية بدلاً منه: «إخفاقات التشفير» (Cryptographic Failures) للبيانات المخزّنة أو المرسلة بلا حماية، و«سوء الضبط الأمني» (Security Misconfiguration) لرسائل الخطأ المفصّلة وإعدادات التصحيح، وفي إصدار 2025 «سوء معالجة الحالات الاستثنائية» (Mishandling of Exceptional Conditions). أما قائمة OWASP API Security Top 10 لعام 2023 فتغطي الاستجابات التي تعيد خصائص أكثر من اللازم تحت البند ⁦API3:2023⁩، «كسر التفويض على مستوى خصائص الكائن» (Broken Object Property Level Authorization). وتحت كل اسم يبقى سؤال المختبِر واحداً: ماذا يكشف النظام، ولمن، وأين تنتهي النسخة؟

لماذا يهم

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

وبالنسبة إلى المختبِر، هذه من أسهل العيوب الأمنية اكتشافاً: لا أدوات هجوم، بل قراءة ما يرسله التطبيق ويخزّنه أصلاً، وهو ما يراه المختبِر الوظيفي كل يوم. لكن المختبِر قد يكون أيضاً مصدراً للانكشاف، عبر لقطات الشاشة وتقارير الأخطاء وبيانات الاختبار المنسوخة من الإنتاج، ولهذا يتناول هذا الدرس اكتشاف الانكشاف من دون التسبب فيه.

ما الذي يُعدّ حساساً، ولماذا الترميز ليس حماية

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

ومهما كانت الفئة، فالترميز (Encoding) ليس حماية. فـ Base64 والترميز بالنسبة المئوية والنظام الست عشري وحمولة رمز JWT كلها قابلة للعكس لدى كل من يحمل السلسلة، كما تُظهر أداتا Base64 Decoder وJWT Decoder في ثانية. لا يحمي البيانات إلا التشفير (Encryption) بمفتاح لا يملكه القارئ، أو التجزئة (Hashing) أحادية الاتجاه لكلمات المرور؛ ويشرح الدرس التالي عن أساسيات التشفير الفرق بينهما. والإخفاء الجزئي (Masking) قاعدة عرض لا حماية: فـ **** 4242 آمن فقط عندما لا يرسل الخادم الرقم الكامل أبداً.

  • بيانات الاعتماد والأسرار: كلمات المرور، ومعرّفات الجلسة، ورموز الوصول والتحديث، ورموز إعادة التعيين والتحقق، ومفاتيح API، والمفاتيح الخاصة. القاعدة: لا تُعرض مرة أخرى بعد إدخالها أو إصدارها، ولا تُسجَّل أبداً، ولا توضع في رابط إلا رمز عشوائي قصير الأجل ذو استخدام واحد، مثل الرمز في رابط إعادة تعيين مُرسل بالبريد.
  • البيانات الشخصية: كل ما يحدد هوية شخص أو يصفه؛ الاسم مع الهاتف أو البريد الإلكتروني، ورقم الهوية الوطنية أو الإقامة، وتاريخ الميلاد، والعنوان، والموقع، والصور. ويعرّف نظام PDPL فئة أشد هي «البيانات الحساسة»، وتشمل البيانات الصحية، والبيانات الجينية والحيوية، والبيانات التي تكشف الأصل العرقي أو المعتقد الديني. القاعدة: لصاحبها أو لدور مخوَّل فقط، وللحقول التي تحتاجها الشاشة فقط.
  • بيانات الدفع: رقم البطاقة وتاريخ انتهائها ورمز التحقق منها، ورقم IBAN. القاعدة: الرقم مُخفى جزئياً في كل مكان، ورمز التحقق لا يُخزَّن ولا يُعاد أبداً.
  • التفاصيل الداخلية: تتبّع المكدس، ونص SQL، ومسارات الملفات، وأسماء المضيفات وعناوين IP الداخلية، وإصدارات البرمجيات، وأعلام التصحيح. القاعدة: رسالة عامة للمستخدم، والتفاصيل في سجل الخادم تحت رقم مرجعي.

جرّبها: مفكّك ترميز Base64 جرّبها: مفكّك ترميز JWT

أين تتسرّب البيانات: الروابط والاستجابات ورسائل الخطأ والسجلات

الروابط صُنعت لتُشارك، ولهذا بالذات يحذّر RFC 9110 من حمل معلومات حساسة فيها. فسلسلة الاستعلام (Query String) في طلب GET تُنسخ إلى سجل المتصفح وإشاراته المرجعية، وإلى سجلات الوصول في خادم الويب وموازن الحمل وشبكة توصيل المحتوى (CDN)، وإلى التحليلات ولقطات شاشة الدعم وأي سكربت خارجي في الصفحة، إذ يستطيع قراءة العنوان كاملاً، وإلى مواقع أخرى عبر ترويسة Referer إذا سمحت سياسة Referrer-Policy في الصفحة بإرسال الرابط كاملاً. لذلك فإن ?sessionId= و?email= و?nationalId= في الروابط والمرشّحات والأزرار المرسلة بالبريد تسرّبات حتى عبر HTTPS، الذي يحمي الاتصال لا النسخ. ومكان البيانات الشخصية والأسرار هو جسم الطلب أو ترويسة؛ والاستثناء المقبول عادةً هو رمز عشوائي قصير الأجل ذو استخدام واحد، مثل الرمز في رابط إعادة التعيين أو التأكيد، على صفحة ترسل Referrer-Policy: no-referrer.

وتتسرّب الاستجابات عندما يعيد الخادم الكائن بدلاً من العرض. فشاشة الملف الشخصي تعرض اسماً، لكن /api/users/42 يحمل passwordHash وotpSecret وnationalId وisAdmin؛ ونقطة نهاية قائمة تعيد هاتف كل عميل لأي مستخدم مسجّل دخوله؛ وحزمة JavaScript تشحن مفتاح API؛ واستجابة تحوي بيانات شخصية بلا Cache-Control: no-store قد تبقى في ذاكرة المتصفح المؤقتة، كما يشرح درس التخزين المؤقت في HTTP. والفحص دائماً للجسم الخام، لا للشاشة.

وتكشف رسائل الخطأ التفاصيل الداخلية. فصفحة ⁦500⁩ فيها تتبّع للمكدس، أو خطأ من قاعدة البيانات يحمل نص SQL، أو مسار ملف، أو إصدار إطار عمل، أو صفحة تصحيح تُركت مفعّلة في بيئة الاختبار، تخبر المهاجم بما يجرّبه بالضبط؛ وتسجيل دخول يجيب «المستخدم غير موجود» لعنوان و«كلمة المرور خاطئة» لآخر يؤكد أي الحسابات موجود. يجب أن يرى المستخدم رسالة عامة مع رقم مرجعي، والتفاصيل مكانها سجل الخادم.

وتتسرّب السجلات بصمت. فالتطبيق الذي يسجّل أجسام الطلبات كاملة يسجّل كل كلمة مرور ورقم بطاقة أُرسلا إليه؛ وسجلات الوصول تحتفظ بكل رابط من الفقرة الأولى؛ ومتعقّبات الأخطاء والتحليلات ومبلّغات الأعطال أطراف ثالثة تتلقى نسخاً؛ ومقتطفات السجلات الملصقة في الدردشة والتذاكر تسافر أبعد. وتسرد ورقة OWASP الإرشادية للتسجيل (Logging Cheat Sheet) بيانات يجب إبقاؤها خارج السجلات، منها كلمات المرور، ومعرّفات الجلسة، ورموز الوصول، ومفاتيح التشفير، وبيانات بطاقات الدفع، والبيانات الشخصية الحساسة مثل البيانات الصحية والمعرّفات الحكومية.

أربعة أماكن تتسرّب فيها البيانات الحساسة، وأين تنتهي كل نسخة من البيانات، والفحص القرائي الذي يكشف التسرّب من دون مهاجمة أي شيء.
أين يتسرّبأين تنتهي النسخةالفحص الآمن
الرابط وسلسلة الاستعلام?sessionId= و?phone= في الروابط والمرشّحات وأزرار البريدسجل المتصفح وإشاراته المرجعية، وسجلات الوصول في الخوادم وشبكة CDN، والتحليلات والسكربتات الخارجية الأخرى في الصفحة، ولقطات الشاشة، ومواقع أخرى عبر Referer إذا سمحت السياسةرشّح لوحة الشبكة بـ ?، وافتح كل رابط بريد أو SMS، وحلّل الروابط المشبوهة. المتوقع: البيانات الشخصية والأسرار في الجسم أو الترويسة، ورابط البريد لا يحمل إلا رمزاً قصير الأجل ذا استخدام واحد
استجابات API والصفحاتpasswordHash وnationalId وهاتف شخص آخر ومفاتيح في حزمة JavaScriptذاكرة المتصفح المؤقتة بلا no-store، وتخزين التطبيق نفسه، وكل تطبيق آخر يستدعي نقطة النهاية نفسها، والتصديرات، ولقطات الشاشةاقرأ الجسم الخام لكل نقطة نهاية تستدعيها شاشة وعلّم كل حقل لا تعرضه؛ وأدرج نقاط نهاية القوائم والبحث والتصدير و«me»
رسائل الخطأتتبّع المكدس ونص SQL ومسار الملف والإصدار؛ «المستخدم غير موجود» مقابل «كلمة المرور خاطئة»شاشة المستخدم، وتذاكر الدعم ومتعقّبات الأخطاء، وملاحظات كل من يتفحّص النظامقيمة مشوّهة واحدة لكل نوع مدخل، وحقل مفقود، وطريقة غير مدعومة؛ واقرأ كل جسم 4xx و5xx. المتوقع: رسالة عامة برقم مرجعي، وردود متطابقة لتسجيل الدخول وإعادة التعيين
السجلات والمراقبةأجسام الطلبات الكاملة بكلمات المرور أو أرقام البطاقات، وترويسات Authorization، وكل رابط من الصف الأولمجمّعات السجلات ونسخها الاحتياطية، وخدمات الأخطاء والتحليلات الخارجية، ورسائل الدردشة والتذاكر التي تُلصق فيها المقتطفاتمع المطور، ابحث في سجلات بيئة الاختبار عن قيم الاختبار الخاصة بك بتعبير نمطي؛ واسأل أي الحقول تُسجَّل وكيف تُخفى

التسرّب ملاحظة تُبلَّغ مع إخفاء القيم جزئياً؛ وما إذا كان قابلاً للاستغلال فأمر يقدّره فريق الأمان.

جرّبها: محلّل عناوين URL

تقليل البيانات: السؤال وراء كل حقل

تقليل البيانات (Data Minimisation) يعني جمع البيانات التي يحتاجها الغرض المعلن فقط، ومعالجتها وعرضها والاحتفاظ بها فقط. يشترطه نظام PDPL، ويسمّيه نظام GDPR الأوروبي مبدأً، وهو أقوى دفاع ضد الانكشاف، لأن البيانات التي لا يحتفظ بها النظام أصلاً لا يمكن أن تتسرّب. وبالنسبة إلى المختبِر يتحول إلى سؤال واحد لكل حقل، يُطرح عند أربع نقاط.

  • الجمع: هل يطلب النموذج بيانات لا تحتاجها الميزة، مثل تاريخ الميلاد لنشرة بريدية؟ كل حقل زائد شرط اختبار وسؤال لمالك المنتج.
  • الإعادة: هل يظهر كل حقل في الاستجابة على شاشة ما لهذا الدور؟ قارن JSON الخام بالواجهة، بما في ذلك نقاط نهاية القوائم والبحث والتصدير و«me»، وهي عادةً الأوسع.
  • التسجيل: أي الحقول يكتبها التطبيق في سجلاته، وأيها مُخفى جزئياً؟ اسأل المطور، ثم تحقق بقيم الاختبار الخاصة بك.
  • الاحتفاظ: بعد أن يحذف مستخدم حسابه، هل تظل البيانات تظهر في البحث والتصديرات والنسخ الاحتياطية للسجلات؟ وهل تحوي بيئة الاختبار نسخة من بيانات الإنتاج أصلاً؟ هذه النسخة بموجب PDPL بيانات شخصية تُعالَج؛ والبيانات الاصطناعية هي الخيار الافتراضي، كما يشرح دليل اختبار قواعد البيانات.

مثال تطبيقي: واجهة API لتتبّع الطلبات

تتضمن خطة اختبار تطبيق توصيل فحصاً للانكشاف في ميزة تتبّع الطلبات الجديدة، بنطاق أكّده مسؤول الأمان كتابةً: بيئة الاختبار، وحسابا العميل والمندوب التجريبيان الخاصان بالمختبِر، ومدخلات غير ضارة فقط. يتلقى العملاء رابط التتبّع برسالة SMS، وتستدعي صفحة التتبّع وتطبيق الجوال كلاهما GET /api/orders/{id}.

الرابط هو https://track.shop.example/t?order=1042&phone=0551234567: رقم هاتف في رابط GET، يُنسخ إلى سجلات مزوّد SMS وسجل المتصفح وسكربت مزوّد الخرائط الذي تضمّنه صفحة التتبّع، إذ يستطيع قراءة العنوان كاملاً. والاستجابة أدناه، عند قراءتها بوصفها JSON خاماً، تحمل رقم البطاقة الكامل ورمز التحقق، ورقم الهوية الوطنية للعميل، وعنوان منزل المندوب، وملاحظة داخلية ومضيف قاعدة بيانات، ولا تعرض شاشة التتبّع أياً منها، وليس فيها ترويسة Cache-Control. ويعيد /api/orders/abc استجابة ⁦500⁩ يذكر جسمها مسار ملف ونص SQL. وأخيراً، يلصق مطور سُئل عمّا تسجّله الواجهة سطراً من سجل التطبيق يحوي جسم POST /login كاملاً، بما فيه كلمة المرور.

يبلّغ المختبِر، مع إخفاء كل قيمة جزئياً، بترتيب الخطورة: أولاً بيانات البطاقة في الاستجابة، لأن رمز التحقق يجب ألا يُحتفظ به بعد اعتماد الدفع، وكلمة المرور في السجل، التي يقرؤها كل من يصل إلى السجلات؛ ثم رقم الهاتف في الرابط، ثم رقم الهوية وعنوان المندوب والملاحظة الداخلية، ثم نص SQL ومسار الملف في جسم الخطأ، ثم غياب Cache-Control: no-store. وتُتفق الخطورة مع فريق الأمان، ويُؤكَّد الإصلاح في كل مكان ظهرت فيه البيانات، لا في شاشة التتبّع وحدها.

GET /api/orders/1042 HTTP/1.1
Host: api.test.shop.example
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI3NzMxIn0.x

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1042,
  "status": "out_for_delivery",
  "customer": { "name": "Test Customer", "phone": "0551234567",
                "nationalId": "1098765432" },
  "payment": { "card": "4242424242424242", "expiry": "12/27", "cvv": "123" },
  "courier": { "name": "Test Courier", "phone": "0509876543",
               "homeAddress": "Al Olaya, Riyadh" },
  "internal": { "note": "complained twice", "dbHost": "10.0.3.12" }
}

GET /api/orders/abc HTTP/1.1
Host: api.test.shop.example

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{ "error": "invalid input syntax for type integer: \"abc\"",
  "query": "SELECT * FROM orders WHERE id = 'abc'",
  "at": "/srv/app/src/orders/service.ts:88" }

جرّبها: عارض شجرة JSON

كيف تختبر الانكشاف بأمان

اختبار الانكشاف قراءة لا هجوم: تنظر فيما يرسله التطبيق ويخزّنه لحسابات الاختبار الخاصة بك، في نظام تملكه أو لديك إذن كتابي باختباره. وبيانات العملاء الحقيقية ليست بيانات اختبار أبداً؛ فإذا صادفتها مصادفةً فتوقف ولا تنسخها وأبلغ مسؤولك. واحتفظ بالأدلة مع إخفاء القيم جزئياً، مثل 05512*****.

  • الجرد: من المتطلبات ونموذج البيانات، اكتب الحقول الحساسة في الميزة، ولكل حقل من يجوز له رؤيته وأين يجوز أن يظهر: الشاشة أو API أو السجل أو التصدير أو البريد أو SMS.
  • الروابط: امشِ في كل مسار ولوحة الشبكة مرشّحة بـ ?، وافتح كل رابط مُرسل بالبريد أو SMS، وحلّل الروابط المشبوهة. المتوقع: لا بيانات شخصية ولا كلمات مرور ولا معرّفات جلسة ولا مفاتيح في أي سلسلة استعلام، ولا شيء في رابط البريد سوى رمز قصير الأجل ذي استخدام واحد.
  • الاستجابات: لكل نقطة نهاية تستدعيها شاشة، اقرأ الجسم الخام وعلّم كل حقل لا تعرضه الشاشة؛ وكرر ذلك لنقاط نهاية القوائم والبحث والتصدير و«me» ولمصدر HTML وحزم JavaScript.
  • الأخطاء: أرسل قيمة مشوّهة واحدة لكل نوع مدخل، وحقلاً مطلوباً مفقوداً، وطريقة غير مدعومة، واقرأ أجسام استجابات 4xx و5xx؛ ويجب أن تجيب عمليات تسجيل الدخول وإنشاء الحساب وإعادة التعيين بالرسالة نفسها للحسابات الموجودة والمجهولة.
  • السجلات والأطراف الثالثة: مع المطور، ابحث في سجلات التطبيق وسجلات الوصول في بيئة الاختبار عن قيم الاختبار الخاصة بك بتعبير نمطي، واكتب أي متعقّبات أخطاء وتحليلات تتلقى الطلبات.
  • جانب العميل: Cache-Control: no-store في الاستجابات التي تحوي بيانات شخصية، وترويسة Referrer-Policy، ومحتوى التخزين المحلي وتخزين الجلسة، وما تطبعه وحدة تحكم المتصفح.

جرّبها: أداة اختبار Regex جرّبها: محلّل مخاطر استجابات API بالذكاء الاصطناعي

أخطاء شائعة

  • الحكم على الانكشاف من الشاشة بدلاً من الاستجابة الخام: فالواجهة تخفي رقم البطاقة جزئياً بينما يحمله JSON كاملاً.
  • اعتبار Base64 أو النظام الست عشري أو حمولة JWT مخفية؛ إنها ترميز، وكل من يحمل السلسلة يستطيع قراءتها.
  • لصق رموز حية أو معرّفات كاملة أو بيانات عميل في تقرير خطأ يقرؤه الجميع: فيصبح التقرير تسرّباً جديداً.
  • فحص استجابات المسار السعيد فقط من دون أجسام الأخطاء ونقاط نهاية القوائم والتصدير ورسائل البريد وروابط SMS.
  • قبول عبارة «إنها بيئة الاختبار فقط»: فإعدادات التصحيح وضبط التسجيل تنتقل إلى الإنتاج عبر خط الأنابيب نفسه، وبيانات الإنتاج المنسوخة إلى بيئة الاختبار انكشاف بحد ذاتها.
  • الخلط بين سؤال الحقل وسؤال الكائن: التحكم في الوصول يسأل هل يجوز لهذا المستخدم رؤية هذا الطلب؛ والانكشاف يسأل أي حقوله يجب أن يتلقاها هذا المستخدم، وأيها لا يجوز أن يتلقاه أحد.

من منظور ضمان الجودة

في فريق حقيقي يبدأ اختبار الانكشاف عند تنقيح المتطلبات. لكل حقل جديد اسأل من يراه، وأين يجوز أن يظهر — الشاشة أو API أو السجل أو التصدير أو البريد أو SMS — وكم يُحتفظ به، واكتب الإجابات شروط اختبار. واسأل المطور هل تُبنى الاستجابة من نموذج عرض (View Model)، أي كائن لا يحمل إلا الحقول التي تحتاجها الشاشة، أم من كيان قاعدة البيانات الخام، وأي الحقول تُسجَّل وتُخفى، واحصل على النطاق والمدخلات الآمنة من مسؤول الأمان كتابةً قبل أن تبدأ.

سجّل كل ملاحظة بوصفها نقطة نهاية وحقلاً ومن تلقّاه وأين تنتهي النسخة والدليل المُخفى جزئياً، بصلاحية رؤية مقيّدة، واتفق على الخطورة مع فريق الأمان الذي يوازن فئة البيانات والجمهور وعدد النسخ. وبعد الإصلاح أكّده في كل مكان ظهرت فيه القيمة — الاستجابة والذاكرة المؤقتة والسجل والتصدير — واحتفظ بفحص انحدار: فاختبار العقد (Contract Test) الذي يتحقق من الاستجابة مقابل مخطط JSON Schema يضع additionalProperties: false على كل كائن يفشل يوم يتسلل حقل جديد إلى الحمولة، في أي مستوى منها.

تمرين عملي

راجع تأكيد موعد في عيادة بحثاً عن الانكشاف

المطلوب

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

ثم اكتب عنوان تقرير الخطأ الأول، وسمّ الفحوص التي ستجريها بعد ذلك.

المادة
E-mail link:
https://clinic.example/appointments/confirm?id=5581&patient=1098765432&otp=482913

GET /api/patients/me/appointments HTTP/1.1   (signed in as patient 7731)

HTTP/1.1 200 OK
Content-Type: application/json

[{
  "id": 5581, "date": "2026-10-09T09:30:00+03:00", "status": "confirmed",
  "patient": { "id": 7731, "name": "Test Patient", "nationalId": "1098765432",
               "insuranceNo": "INS-44120", "diagnosisHistory": ["..."] },
  "doctor": { "name": "Dr. Test", "mobile": "0551112222", "licenceNo": "D-9981" },
  "clinic": { "name": "Olaya branch", "dbHost": "10.20.0.5", "env": "test" }
}]

GET /api/patients/me/appointments?date=next-week HTTP/1.1

HTTP/1.1 500 Internal Server Error
{ "error": "invalid input syntax for type date: \"next-week\"",
  "at": "/srv/clinic/api/appointments/list.js:41" }
الخطوات
  1. صنّف كل قيمة في العيّنات الثلاث: سرّ، أو بيانات شخصية، أو بيانات شخصية حساسة، أو بيانات دفع، أو تفاصيل داخلية.
  2. لرابط البريد الإلكتروني، اكتب أين سيُنسخ الرابط.
  3. قارن حقول الاستجابة بما تحتاجه صفحة المواعيد، وعلّم كل حقل زائد.
  4. اقرأ جسم الخطأ، وقرر ما الذي يجب أن يراه المستخدم بدلاً منه.
  5. اكتب الملاحظات بترتيب الخطورة مع إخفاء القيم جزئياً.
إظهار الإجابة النموذجية
الإجابة النموذجية

الرابط: patient= رقم هوية وطنية (بيانات شخصية) وotp= رمز لمرة واحدة (سرّ) في رابط GET، يُنسخان إلى خوادم البريد وسجل المتصفح وسجلات وصول العيادة وأي سكربت خارجي في صفحة التأكيد، وإلى ترويسة Referer المرسلة إلى مواقع أخرى إذا سمحت سياسة Referrer-Policy بالرابط الكامل. المتوقع: لا رقم هوية ولا رمز OTP في الرابط، بل رمز مبهم عشوائي يصلح مرة واحدة لهذا التأكيد ثم تنتهي صلاحيته، مع Referrer-Policy: no-referrer في صفحة التأكيد.

الاستجابة: nationalId وinsuranceNo (بيانات شخصية) وdiagnosisHistory (بيانات صحية، وهي بيانات شخصية حساسة بموجب PDPL) غير مطلوبة لعرض قائمة المواعيد؛ وmobile الطبيب بيانات شخصية لشخص آخر ورقم ترخيصه غير مطلوب؛ وclinic.dbHost وenv تفاصيل داخلية؛ ولا تظهر أي بيانات دفع. الصيغة الأدنى: المعرّف والتاريخ والحالة واسم الطبيب واسم العيادة. وتحتاج الاستجابة أيضاً إلى Cache-Control: no-store.

الخطأ: يكشف رسالة محرك قاعدة البيانات ومسار ملف، ويبيّن أن المدخل وصل إلى قاعدة البيانات من دون تحقق؛ يجب أن يتلقى المستخدم ⁦400⁩ مع «تاريخ غير صالح» ورقم مرجعي، والتفاصيل في سجل الخادم.

ترتيب الخطورة مع إخفاء القيم: أولاً رقم الهوية الوطنية 10987***** ورمز OTP ****** في الرابط، لأن الرابط يصل إلى خوادم البريد وأطراف ثالثة بينما لا تصل الاستجابة إلا إلى المريض المسجّل دخوله؛ ثم diagnosisHistory وnationalId وinsuranceNo في استجابة بلا no-store؛ ثم جوال الطبيب 05511*****؛ وأخيراً التفاصيل الداخلية في الاستجابة وجسم الخطأ.

عنوان تقرير الخطأ: «رابط تأكيد الموعد يحمل رقم الهوية الوطنية للمريض ورمز OTP في سلسلة الاستعلام». الخطورة المقترحة: حرج (Critical)، وتُعتمد بالاتفاق مع فريق الأمان.

التالي: البحث في سجل الخادم عن رمز OTP ورقم الهوية مع المطور، وفحص تصدير المواعيد وملف PDF ونص SMS، وقراءة استجابة تطبيق الطبيب.

أسئلة شائعة

هل ما زال انكشاف البيانات الحساسة فئة في OWASP Top 10؟

ليس بهذا الاسم. فقد أعاد إصدار 2021 تسميته «إخفاقات التشفير» للإشارة إلى سبب جذري، وتقع رسائل الخطأ المفصّلة وإعدادات التصحيح تحت «سوء الضبط الأمني». وتغطي قائمة OWASP API Security Top 10 لعام 2023 الاستجابات الأوسع من اللازم تحت «كسر التفويض على مستوى خصائص الكائن». التسرّبات هي نفسها؛ تغيّرت التسميات فقط.

هل من المشكلة أن تعيد الواجهة بياناتي أنا إليّ؟

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

ماذا أفعل إذا وجدت بيانات عملاء حقيقية في بيئة الاختبار؟

توقف، ولا تنسخها ولا تلتقط لها صورة، وأبلغ مسؤولك أو مسؤول حماية البيانات. فبموجب PDPL تظل نسخة الإنتاج في بيئة الاختبار بيانات شخصية تُعالَج. واطلب بيانات اختبار اصطناعية أو مجهّلة الهوية قبل المتابعة، كما يصف دليل اختبار قواعد البيانات.

رمز JWT يحمل البريد الإلكتروني للمستخدم ودوره. هل هذا انكشاف؟

حمولة رمز JWT الموقّع المعتاد مرمّزة بـ Base64url فقط لا مشفّرة، فكل من يحمل الرمز يستطيع قراءتها. ومطالبة الدور أمر طبيعي؛ أما رقم الهوية أو رقم الهاتف أو كلمة المرور في الحمولة فانكشاف. ومكان حفظ الرمز مهم أيضاً: ففي التخزين المحلي يستطيع أي سكربت في الصفحة قراءته. فكّ ترميز رموز الاختبار بأداة JWT Decoder وقارن المطالبات بجرد البيانات.

المراجع

  • OWASP Top 10:2025OWASP Foundation · 2025أخطر عشرة مخاطر أمنية لتطبيقات الويب، مع كيفية اختبار كل منها والوقاية منه.
  • OWASP API Security Top 10 (2023)OWASP Foundation · 2023أكثر عشر نقاط ضعف شيوعاً في واجهات API: خلل التفويض على مستوى الكائن، وخلل التوثيق، والاستهلاك غير المقيد للموارد، وغيرها.
  • OWASP Cheat Sheet Series: LoggingOWASP Foundationما يُسجَّل وما لا يُسجَّل أبداً (كلمات المرور والرموز والبيانات الشخصية)، وكيف تُبقى السجلات قابلة لكشف العبث.
  • Personal Data Protection Law (English translation)الهيئة السعودية للبيانات والذكاء الاصطناعي (سدايا) · 2023النظام السعودي لحماية البيانات الشخصية — ولماذا ينبغي أن تستخدم بيئات الاختبار بيانات اصطناعية بدلاً من نسخ سجلات العملاء الحقيقية.

تدرّب بأدوات متقن

تفكيك عنوان URL إلى البروتوكول والمضيف والمنفذ والمسار ومعاملات الاستعلام والجزء (fragment) وبيانات الاعتماد.

الويب

استكشاف JSON كشجرة قابلة للطي مع المسارات والأنواع وعدد القيم.

JSON والبيانات

فكّ ترميز ترويسة JWT وحمولته، وفحص المطالبات (claims) والتحقق من انتهاء الصلاحية — بالكامل داخل متصفحك.

الأمان

فكّ ترميز سلاسل Base64 أو Base64url إلى نص، مع إصلاح الحشو تلقائياً.

الترميز

اختبر التعابير النمطية مباشرةً مع إبراز التطابقات ومجموعات الالتقاط ومعاينة الاستبدال.

أدوات مساعدة

قيّم مخاطر الأمان والخصوصية في استجابة API: كشف البيانات الشخصية (PII)، والأخطاء المفصّلة أكثر من اللازم، والترويسات غير الآمنة، وتلميحات التعداد.

تحليل الأخطاء ذكاء اصطناعي

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة