php - تطهير كلمات مرور المستخدم




sql pdo (2)

كيف يمكنني الهروب أو مسح كلمات المرور التي يوفرها المستخدم قبل تجميعها وتخزينها في قاعدة البيانات الخاصة بي؟

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


قبل تجزئة كلمة المرور ، يجب عليك تطبيعها كما هو موضح في القسم 4 من RFC 7613 . خاصه:

  1. قاعدة التعيين الإضافية: يجب تعيين أي مثيلات لمجال غير ASCII إلى مساحة ASCII (U + 0020) ؛ مساحة غير ASCII هي أي نقطة رمز Unicode لها فئة عامة لـ Unicode من "Zs" (باستثناء U + 0020).

و:

  1. قاعدة التطبيع: يجب تطبيق نموذج تسوية Unicode C (NFC) على جميع الأحرف.

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


يجب ألا تهرب أبدًا أو تقطع أو تستخدم أي آلية تطهير أخرى على كلمات المرور التي ستقوم بإزالتها باستخدام password_hash() PHP الخاص بـ PHP لعدة أسباب ، أكبرها هو أن القيام بعملية تطهير إضافية لكلمة المرور تتطلب رمزًا إضافيًا غير ضروري.

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

فعل تجزئة كلمة المرور هو فعل جعل كلمة المرور آمنة لتخزينها في قاعدة البيانات الخاصة بك. لا تعطي وظيفة التجزئة أي معنى خاص لأي بايت ، لذلك لا يلزم تطهير مدخلاتها لأسباب أمنية

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

يتم استخدام PASSWORD_BCRYPT لإنشاء تجزئة كلمة مرور جديدة باستخدام خوارزمية CRYPT_BLOWFISH. سيؤدي هذا دائمًا إلى تجزئة باستخدام تنسيق التشفير "$ 2y $" ، والذي يبلغ عرضه دائمًا 60 حرفًا.

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

يمكنك استخدام استعلام SQL كامل ككلمة مرورك وسيتم تجزئته ، مما يجعله غير قابل للتنفيذ بواسطة محرك SQL على سبيل المثال ،

SELECT * FROM `users`;

يمكن تجزئة إلى $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

لنرى كيف تؤثر طرق التعقيم المختلفة على كلمة المرور -

كلمة المرور هي I'm a "dessert topping" & a <floor wax>! (هناك 5 مسافات في نهاية كلمة المرور لا يتم عرضها هنا.)

عندما نطبق الطرق التالية للتشذيب ، نحصل على بعض النتائج المختلفة:

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

النتائج:

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

ماذا يحدث عندما نرسل هذه إلى password_hash() ؟ يتم تجزئة الكل ، تمامًا كما فعل الاستعلام أعلاه. المشكلة تأتي عند محاولة التحقق من كلمة المرور. إذا استخدمنا واحدة أو أكثر من هذه الطرق ، فيجب علينا إعادة توظيفها قبل مقارنتها password_verify() . سوف تفشل ما يلي:

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

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

باستخدام نسخة PHP أقل من 5.5؟ يمكنك استخدام حزمة التوافق password_hash() .

يجب ألا تستخدم علامات تجزئة كلمة المرور MD5 .







hash