واجهة الغربان تستخدم رمز JWT لتعرف من أنت الرمز فيه ترويسة تحدد خوارزمية التوقيع والهاكر ترك المكتبة تقبل القيمة none أي رمز بلا توقيع أصلا أنت تملك رمز guest
واجهة الغربان تتحقق من جلستك برمز JWT تضعه في ترويسة Authorization. التطبيق يعرض رمزك الحالي guest ويتيح لك تعديل الترويسة والحمولة واختيار طريقة التوقيع الخادم يثق بأي رمز ترويسته alg none بلا توقيع
لماذا نجح الحل
الرمز JWT يقول في ترويسته كيف وقع والخطأ أن الخادم يصدق هذي الترويسة فإذا قالت none قبل الرمز بلا أي توقيع فأي أحد يكتب أي حمولة الحل: الخادم يحدد الخوارزمية المقبولة بنفسه ولا يقرأها من الرمز ويرفض none دائما ويتحقق من التوقيع بمفتاح سري قوي ثم يثق بالحمولة
السبب الجذري
الخادم يقرأ الخوارزمية من ترويسة الرمز وهي بيانات يتحكم بها المهاجم ويطيعها فيقبل alg none بلا تحقق من التوقيع التحقق يجب أن يفرض خوارزمية متوقعة لا أن يأخذها من الرمز
كيف يصلح الكود
الخوارزمية قرار الخادم لا قرار الرمز none ليست خوارزمية توقيع إنها غياب توقيع
الكود المصاب
function verify(token) {
const { header, payload, signature } = parse(token);
if (header.alg === 'none') return payload; // trusts an unsigned token
if (!checkHmac(signingInput, signature, SECRET)) throw new Error('bad');
return payload;
}
الكود الآمن
function verify(token) {
// The server decides the algorithm; it never reads it from the token, and never accepts none.
return jwt.verify(token, SECRET, { algorithms: ['HS256'] });
}
الأثر في الواقع
ثغرة alg none سمحت تاريخيا بتزوير أي رمز وانتحال أي مستخدم في مكتبات JWT شهيرة دون معرفة أي سر
كيف يكتشفها المدافعون
المدافع يرفض alg none صراحة ويثبت الخوارزمية المسموحة في كود التحقق ويرصد رموزا بترويسة none أو بتوقيع فارغ