سؤال

أنا أكتب تطبيقًا هو الغرض الرئيسي هو الحفاظ على قائمة مشتريات المستخدمين.

أود أن أتأكد من أنه حتى أنا كمطور (أو أي شخص لديه وصول كامل إلى قاعدة البيانات) لم يتمكن من معرفة مقدار الأموال التي أنفقها شخص معين أو ما شتاه.

لقد توصلت في البداية إلى المخطط التالي:

    --------------+------------+-----------
    user_hash     | item       | price
    --------------+------------+-----------
    a45cd654fe810 | Strip club |     400.00
    a45cd654fe810 | Ferrari    | 1510800.00
    54da2241211c2 | Beer       |       5.00
    54da2241211c2 | iPhone     |     399.00
  • يقوم المستخدم بتسجيل الدخول باستخدام اسم المستخدم وكلمة المرور.
  • من حساب كلمة المرور user_hash (ربما مع التملين وما إلى ذلك).
  • استخدم التجزئة للوصول إلى بيانات المستخدمين باستخدام SQL-feries العادية.

بالنظر إلى عدد كاف من المستخدمين ، يجب أن يكون من المستحيل تقريبًا معرفة مقدار الأموال التي أنفقها المستخدم معين من خلال معرفة اسمه.

هل هذا شيء معقول ، أم أنا أحمق تمامًا؟

هل كانت مفيدة؟

المحلول

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

لا توجد طريقة على الإطلاق للوقاية من هذا.

والحقيقة هي أنه من خلال الوصول الكامل ، نحن في وضع الثقة. هذا يعني أن على مديري الشركة أن يثقوا في أنه على الرغم من أنه يمكنك رؤية البيانات ، فلن تتصرف بأي شكل من الأشكال. هذا هو المكان الذي تلعب فيه الأشياء الصغيرة مثل الأخلاق.

الآن ، ومع ذلك ، تفصل الكثير من الشركات عن موظفي التطوير والإنتاج. والغرض من ذلك هو إزالة التطوير من الاتصال المباشر ببيانات Live (IE: حقيقية). هذا له عدد من المزايا مع وجود أمان وموثوقية البيانات في الجزء العلوي من الكومة.

العيب الحقيقي الوحيد هو ذلك بعض يعتقد المطورون أنهم لا يستطيعون استكشاف مشكلة دون الوصول إلى الإنتاج. بالرغم من ذلك فان هذا وبكل بساطة ليس حقيقة.

سيكون موظفو الإنتاج هم الوحيدون الذين لديهم إمكانية الوصول إلى الخوادم الحية. عادة ما يتم فحصها إلى درجة أكبر (التاريخ الإجرامي وفحوصات الخلفية الأخرى) التي تتوافق مع نوع البيانات التي يجب أن تحميها.

الهدف من كل هذا هو أن هذه مشكلة الموظفين ؛ وليس الشخص الذي يمكن حله حقًا بالوسائل الفنية.


تحديث

يبدو أن الآخرين هنا يفتقدون قطعة مهمة للغاية وحيوية من اللغز. وهي أنه يتم إدخال البيانات في النظام لسبب ما. هذا السبب يكاد يكون عالميًا تقريبًا بحيث يمكن مشاركته. في حالة تقرير النفقات ، يتم إدخال هذه البيانات بحيث يمكن للمحاسبة معرفة من الذي يجب سداده.

مما يعني أن النظام ، على مستوى ما ، سيتعين عليه مطابقة المستخدمين والعناصر دون تسجيل الدخول إلى شخص إدخال البيانات (أي: مندوب مبيعات).

ولأن هذه البيانات يجب ربطها معًا دون أن تتضمن جميع الأطراف الوقوف هناك لتكتب رمز الأمان "لإصدار" البيانات ، فإن DBA ستتمكن تمامًا من مراجعة سجلات الاستعلام لمعرفة من هو. وبسهولة ، قد أضيف بغض النظر عن عدد علامات التجزئة التي تريد رميها فيها. Triple des لن ينقذك أيضًا.

في نهاية اليوم ، كل ما قمت به هو جعل التطوير أكثر صعوبة مع فائدة أمنية على الإطلاق. لا يمكنني التأكيد على هذا بما فيه الكفاية: الطريقة الوحيدة لإخفاء البيانات من DBA هي إما 1. تلك البيانات إلى فقط يكون متاحًا من قبل الشخص الذي دخلها أو 2. حتى لا يكون موجودًا في المقام الأول.

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

نصائح أخرى

أخشى أنه إذا تمكن التطبيق الخاص بك من ربط شخص ما ببياناته ، يمكن لأي مطور/مسؤول.

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


فكرة تستند إلى فكرة @no:

يمكن أن يكون لديك تسجيل دخول كلاسيكي/كلمة مرور إلى تطبيقك (كلمة مرور التجزئة ، أو أي شيء آخر) ، و "تمريرة" خاصة تستخدم للحفاظ على آمنة البيانات الخاصة بك. لن يتم تخزين هذا "المرور" في قاعدة البيانات الخاصة بك.

عندما يقوم العميل بتسجيل الدخول إلى التطبيق الخاص بك ، سيتعين عليّ تقديم المستخدم/كلمة المرور/المرور. يتم التحقق من المستخدم/كلمة المرور باستخدام قاعدة البيانات ، وسيتم استخدام التمرير لتحميل/كتابة البيانات.

عندما تحتاج إلى كتابة البيانات ، يمكنك إنشاء تجزئة من زوجك "اسم المستخدم/المرور" ، وتخزينها كمفتاح يربط عميلك ببياناتك.

عندما تحتاج إلى تحميل البيانات ، يمكنك صنع تجزئة من زوجك "اسم المستخدم/المرور" ، وتحميل كل بيانات تطابق هذا التجزئة.

وبهذه الطريقة ، من المستحيل إنشاء رابط بين بياناتك ومستخدمك.

في جهة أخرى ، (كما قلت في تعليق على NO) احذر من الاصطدامات. بالإضافة إلى ذلك ، إذا كتب المستخدم "تمريرة" سيئة ، فلن تتمكن من التحقق من ذلك.


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

  1. قم بإنشاء جدول مستخدمين مع:
    1. user_id: عمود هوية (معرف تم إنشاؤه تلقائيًا)
    2. اسم االمستخدم
    3. كلمة المرور: تأكد من أنها تجزئة!
  2. قم بإنشاء جدول منتج كما في مثالك:
    1. user_hash
    2. العنصر
    3. سعر

سيتم استناد user_hash من user_id الذي لا يتغير أبدًا. اسم المستخدم وكلمة المرور حرة في التغيير حسب الحاجة. عندما يقوم المستخدم بتسجيل الدخول ، يمكنك مقارنة اسم المستخدم/كلمة المرور للحصول على user_id. يمكنك إرسال user_hash إلى العميل طوال فترة الجلسة ، أو إصدار مشفر/غير مباشر من التجزئة (يمكن أن يكون معرف جلسة ، حيث يقوم الخادم بتخزين user_hash في الجلسة).

أنت الآن بحاجة إلى وسيلة لتجزئة user_id في user_hash والحفاظ عليها محمية.

  1. إذا قمت بذلك ، في جانب العميل كما اقترح NO ، يحتاج العميل إلى الحصول على user_id. حفرة الأمان الكبيرة (خاصة إذا كان تطبيق ويب) ، يمكن بسهولة العبث بالتجزئة والخوارزمية متاحة مجانًا للجمهور.
  2. يمكن أن يكون لها وظيفة في قاعدة البيانات. فكرة سيئة ، نظرًا لأن قاعدة البيانات تحتوي على جميع القطع لربط السجلات.
  3. بالنسبة لمواقع الويب أو تطبيقات العميل/الخادم ، يمكنك الحصول عليها على رمز جانب الخادم الخاص بك. أفضل بكثير ، ولكن بعد ذلك يمكن لمطور واحد الوصول إلى خوارزمية التجزئة والبيانات.
  4. اطلب من مطور آخر كتابة خوارزمية التجزئة (التي لا يمكنك الوصول إليها) والتمسك بها على خادم آخر (لا يمكنك الوصول إليه أيضًا) كخدمة TCP/Web. سيقوم رمز جانب الخادم الخاص بك بعد ذلك بتمرير معرف المستخدم واستعادة تجزئة. لن يكون لديك الخوارزمية ، ولكن يمكنك إرسال جميع معرفات المستخدم لاستعادة جميع تجزئةها. ليس هناك الكثير من الفوائد إلى رقم 3 ، على الرغم من أن الخدمة يمكن أن يكون لها تسجيل ومحاولة تقليل المخاطر.
  5. إذا كان مجرد تطبيق database عميل ، فلديك خيارات #1 و 2. أقترح بشدة إضافة طبقة أخرى [أعمال] من جانب الخادم ، منفصلة عن خادم قاعدة البيانات.

يحرر:هذا يتداخل بعض النقاط السابقة. لديك 3 خوادم:

  • خادم المصادقة: الموظف A لديه الوصول. يحافظ على جدول المستخدم. لديه خدمة ويب (مع الاتصالات المشفرة) التي تأخذ مجموعة المستخدم/كلمة المرور. تجزئة كلمة المرور ، والبحث عن user_id في الجدول ، ويقوم بإنشاء user_hash. وبهذه الطريقة ، لا يمكنك ببساطة إرسال جميع user_ids واستعادة التجزئة. يجب أن يكون لديك كلمة المرور التي لم يتم تخزينها في أي مكان وهي متوفرة فقط أثناء عملية المصادقة.
  • خادم قاعدة البيانات الرئيسي: الموظف ب لديه الوصول. يخزن فقط user_hash. لا يوجد مستخدم ، لا كلمات مرور. يمكنك ربط البيانات باستخدام user_hash ، ولكن معلومات المستخدم الفعلية في مكان آخر.
  • خادم الموقع: الموظف ب لديه الوصول. تحصل على معلومات تسجيل الدخول ، وينتقل إلى خادم المصادقة ، واستعادة التجزئة ، ثم التخلص من معلومات تسجيل الدخول. يحافظ على التجزئة في الجلسة للكتابة/الاستعلام إلى قاعدة البيانات.

لذلك الموظف A لديه user_id ، اسم المستخدم ، كلمة المرور والخوارزمية. الموظف B لديه user_hash والبيانات. ما لم يكن الموظف B يعدل موقع الويب لتخزين المستخدم/كلمة المرور الخام ، فلن يكون لديه أي طريقة للربط بالمستخدمين الحقيقيين.

باستخدام التنميط SQL ، سيحصل الموظف A على user_id واسم المستخدم وكلمة المرور (منذ أن تم إنشاء user_hash لاحقًا في التعليمات البرمجية). سيحصل الموظف B على user_hash والبيانات.

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

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

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

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

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

لهذا السبب ، عندما تقوم بإلغاء تحديد السجلات الطبية (للاستخدام في البحث وما شابه) ، يجب عليك إزالة أعياد الميلاد للأشخاص الذين تزيد أعمارهم عن 89 عامًا (لأن الأشخاص الذين يبلغون من العمر نادرون بما يكفي لدرجة أن عملية ميلاد معينة يمكن أن تشير إلى شخص واحد) وإزالة أي ترميز جغرافي يحدد منطقة تحتوي على أقل من 20،000 شخص. (نرى http://privacy.med.miami.edu/glossary/xd_deidentifution_health_info.htm)

اكتشف AOL بالطريقة الصعبة عندما أصدروا بيانات البحث التي يمكن أن يتم تحديد الأشخاص فقط من خلال معرفة عمليات البحث المرتبطة بشخص مجهول. (نرى http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)

يبدو أنك على الطريق الصحيح مع هذا ، لكنك أكثر من التفكير في الأمر (أو أنا ببساطة لا أفهمه)

اكتب وظيفة تبني سلسلة جديدة بناءً على الإدخال (والتي ستكون اسم المستخدم أو أي شيء آخر لا يمكن تغيير العمل الإضافي)

استخدم السلسلة التي تم إرجاعها كملح عند إنشاء تجزئة المستخدم (مرة أخرى ، سأستخدم معرف المستخدم أو اسم المستخدم كمدخل لباني التجزئة لأنهم لن يتغيروا مثل كلمة مرور المستخدمين أو البريد الإلكتروني)

قم بربط جميع إجراءات المستخدم مع تجزئة المستخدم.

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

أعتقد أنك أجبت على سؤالك مع مشاركتك الأولية.

في الواقع ، هناك طريقة يمكن أن تفعل ما تتحدث عنه ...

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

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

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

تعديل

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

على سبيل المثال ، تأخذ مولد التجزئة مثل هذا:

http://baagoe.com/en/randommusings/javascript/mash.js

// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagoe <baagoe@baagoe.com>, 2010
function Mash() {
  var n = 0xefc8249d;

  var mash = function(data) {
    data = data.toString();
    for (var i = 0; i < data.length; i++) {
      n += data.charCodeAt(i);
      var h = 0.02519603282416938 * n;
      n = h >>> 0;
      h -= n;
      h *= n;
      n = h >>> 0;
      h -= n;
      n += h * 0x100000000; // 2^32
    }
    return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
  };

  mash.version = 'Mash 0.9';
  return mash;
}

أنظر كيف n التغييرات ، في كل مرة تقوم فيها بسلسلة تحصل على شيء مختلف.

  • تجزئة اسم المستخدم+كلمة مرور باستخدام علامة التجزئة العادية. سيكون هذا هو نفس مفتاح الجدول "السري" في قاعدة البيانات ، ولكنه لن يتطابق مع أي شيء آخر في قاعدة البيانات.
  • قم بإلحاق تمريرة التجزئة إلى اسم المستخدم وتجزئة ذلك مع الخوارزمية أعلاه.
  • BASE-16 تشفير var n وإلحاقها في التجزئة الأصلية مع شخصية محدد.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top