سؤال

يتعلق هذا على وجه التحديد عند استخدام ملف تعريف ارتباط جلسة العميل لتحديد جلسة على الخادم.

هل هي أفضل إجابة لاستخدام تشفير SSL/HTTPS لموقع الويب بأكمله، ولديك أفضل ضمان بعدم تمكن أي شخص في الهجمات الوسطى من استنشاق ملف تعريف ارتباط جلسة العميل الحالي؟

وربما يكون ثاني أفضل استخدام هو استخدام نوع من التشفير على قيمة الجلسة نفسها المخزنة في ملف تعريف الارتباط الخاص بجلستك؟

إذا كان لدى مستخدم ضار حق الوصول الفعلي إلى الجهاز، فلا يزال بإمكانه النظر إلى نظام الملفات لاسترداد ملف تعريف ارتباط صالح للجلسة واستخدامه لاختطاف الجلسة؟

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

المحلول

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

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

يحرر:تمت كتابة هذه الإجابة في الأصل في عام 2008.نحن الآن في عام 2016، وليس هناك سبب لعدم وجود SSL عبر موقعك بالكامل.لا مزيد من النص العادي HTTP!

نصائح أخرى

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

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

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

SessionUUID، الرقم التسلسلي، التاريخ/الوقت الحالي

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

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

هل فكرت في قراءة كتاب عن أمان PHP؟ينصح به بشده.

لقد حققت نجاحًا كبيرًا باستخدام الطريقة التالية للمواقع غير المعتمدة من SSL.

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

  2. استخدام الارتباطات التشعبية القائمة على العلاقة يولد رابط (على سبيل المثال. http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) يتم إلحاق الرابط بسلسلة MD5 المملحة العشوائية (الحجم المفضل) ، عند إعادة توجيه الصفحة ، يتوافق الرمز المميز الذي تم إنشاؤه عشوائيًا مع صفحة مطلوبة.

    • عند إعادة التحميل، يتم إجراء العديد من الفحوصات.
    • عنوان IP الأصلي
    • HTTP_USER_AGENT
    • رمز الجلسة
    • تحصل على هذه النقطة.
  3. ملف تعريف الارتباط للمصادقة على الجلسة القصيرة مدى الحياة.كما هو مذكور أعلاه، فإن ملف تعريف الارتباط الذي يحتوي على سلسلة آمنة، والذي يعد أحد المراجع المباشرة لصلاحية الجلسات يعد فكرة جيدة.اجعله تنتهي صلاحيته كل x دقيقة، وأعد إصدار هذا الرمز المميز، وأعد مزامنة الجلسة مع البيانات الجديدة.في حالة وجود أي عدم تطابق في البيانات، قم بتسجيل خروج المستخدم، أو اطلب منه إعادة مصادقة جلسته.

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

// Collect this information on every request
$aip = $_SERVER['REMOTE_ADDR'];
$bip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$agent = $_SERVER['HTTP_USER_AGENT'];
session_start();

// Do this each time the user successfully logs in.
$_SESSION['ident'] = hash("sha256", $aip . $bip . $agent);

// Do this every time the client makes a request to the server, after authenticating
$ident = hash("sha256", $aip . $bip . $agent);
if ($ident != $_SESSION['ident'])
{
    end_session();
    header("Location: login.php");
    // add some fancy pants GET/POST var headers for login.php, that lets you
    // know in the login page to notify the user of why they're being challenged
    // for login again, etc.
}

ما يفعله هذا هو التقاط معلومات "سياقية" حول جلسة المستخدم، وهي أجزاء من المعلومات التي لا ينبغي أن تتغير خلال فترة الجلسة الواحدة.لن يكون المستخدم على جهاز كمبيوتر في الولايات المتحدة والصين في نفس الوقت، أليس كذلك؟لذلك، إذا تغير عنوان IP فجأة خلال نفس الجلسة، فهذا يعني بقوة وجود محاولة اختطاف للجلسة، لذا يمكنك تأمين الجلسة عن طريق إنهاء الجلسة وإجبار المستخدم على إعادة المصادقة.يؤدي هذا إلى إحباط محاولة الاختراق، ويضطر المهاجم أيضًا إلى تسجيل الدخول بدلاً من الوصول إلى الجلسة.قم بإعلام المستخدم بالمحاولة (أياكس الأمر قليلاً)، وvola، مستخدم منزعج قليلاً + مستنير وجلسته/معلوماته محمية.

نحن نستخدم وكيل المستخدم وX-FORWARDED-FOR لبذل قصارى جهدنا لالتقاط تفرد الجلسة للأنظمة الموجودة خلف الوكلاء/الشبكات.قد تتمكن من استخدام المزيد من المعلومات، فلا تتردد في أن تكون مبدعًا.

إنها ليست 100%، لكنها فعالة جدًا.

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

تنتهي صلاحية الجلسات، ولا تدعها تظل صالحة إلى أجل غير مسمى.

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

جرب بروتوكول ملفات تعريف الارتباط الآمنة الموضح في هذا ورقة كتبها ليو وكوفاكس وهوانغ وجودا:

كما جاء في الوثيقة:

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

أما بالنسبة لسهولة النشر:

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

باختصار:إنه آمن وخفيف الوزن ويعمل بشكل رائع بالنسبة لي.

لا توجد طريقة لمنع اختطاف الجلسة بنسبة 100%، ولكن مع بعض الأساليب، يمكننا تقليل الوقت الذي يستغرقه المهاجم لاختطاف الجلسة.

طريقة منع اختطاف الجلسة:

1 - استخدم دائمًا الجلسة مع شهادة SSL؛

2 - إرسال ملف تعريف ارتباط الجلسة فقط مع تعيين httponly على true (منع جافا سكريبت من الوصول إلى ملف تعريف ارتباط الجلسة)

2 - استخدم معرف تجديد الجلسة عند تسجيل الدخول وتسجيل الخروج (ملاحظة:لا تستخدم تجديد الجلسة عند كل طلب لأنه إذا كان لديك طلب أياكس متتالي، فستكون لديك فرصة لإنشاء جلسات متعددة.)

3 - تحديد مهلة الجلسة

4 - تخزين وكيل مستخدم المتصفح في متغير $_SESSION ومقارنته بـ $_SERVER['HTTP_USER_AGENT'] عند كل طلب

5 - قم بتعيين ملف تعريف الارتباط المميز، واضبط وقت انتهاء صلاحية ملف تعريف الارتباط هذا على 0 (حتى يتم إغلاق المتصفح).قم بإعادة إنشاء قيمة ملف تعريف الارتباط لكل طلب. (بالنسبة لطلب أياكس، لا تقم بإعادة إنشاء ملف تعريف الارتباط المميز).السابق:

    //set a token cookie if one not exist
    if(!isset($_COOKIE['user_token'])){
                    //generate a random string for cookie value
        $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

        //set a session variable with that random string
        $_SESSION['user_token'] = $cookie_token;
        //set cookie with rand value
        setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
    }

    //set a sesison variable with request of www.example.com
    if(!isset($_SESSION['request'])){
        $_SESSION['request'] = -1;
    }
    //increment $_SESSION['request'] with 1 for each request at www.example.com
    $_SESSION['request']++;

    //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it's equal then regenerete value of token cookie if not then destroy_session
        if($_SESSION['user_token'] === $_COOKIE['user_token']){
            $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

            $_SESSION['user_token'] = $cookie_token;

            setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
        }else{
            //code for session_destroy
        }

    }

            //prevent session hijaking with browser user agent
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
      die('session hijaking - user agent');
    }

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

6 - ليس من الجيد استخدام عنوان IP الخاص بالمستخدم لمنع اختطاف الجلسة لأن عنوان IP الخاص ببعض المستخدمين يتغير مع كل طلب.التي تؤثر على المستخدمين الصالحين

7 - أنا شخصياً أقوم بتخزين بيانات الجلسة في قاعدة البيانات، والطريقة التي ستتبعها متروك لك

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

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

هناك العديد من الطرق لتوفير الحماية ضد اختطاف الجلسة، إلا أن جميعها إما تقلل من رضا المستخدم أو أنها غير آمنة.

  • فحوصات IP و/أو X-FORWARDED-FOR.هذه تعمل، وهي آمنة جدًا ...لكن تخيل ألم المستخدمين.يأتون إلى مكتب مزود بشبكة WiFi، ويحصلون على عنوان IP جديد ويفقدون الجلسة.حصلت على تسجيل الدخول مرة أخرى.

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

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

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

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

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

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

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

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

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sessionKey = (String) session.getAttribute("sessionkey");
    String remoteAddr = request.getRemoteAddr();
    int remotePort = request.getRemotePort();
    String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort);
    if (sessionKey == null || sessionKey.isEmpty()) {
        session.setAttribute("sessionkey", sha256Hex);
        // save mapping to memory to track which user attempted
        Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort);
    } else if (!sha256Hex.equals(sessionKey)) {
        session.invalidate();
        response.getWriter().append(Application.userSessionMap.get(sessionKey));
        response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); 
        response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex));
        return;
    }
    response.getWriter().append("Valid Session\n");
}

لقد استخدمت خوارزمية SHA-2 لتجزئة القيمة باستخدام المثال الوارد في SHA-256 التجزئة في baeldung

نتطلع لتعليقاتك.

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

يمكن أيضًا أن يكون التحقق من الرؤوس المرجعية خيارًا، ولكن يمكن خداعها بسهولة أكبر.

الحماية عن طريق:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top