অ্যাডমিন সাবডোমেইন CSRF থামায় না: চালুর আগে চারটি পরীক্ষা
নতুন হোস্টনেম নতুন অরিজিন, প্রায়ই একই সাইট, তাই same-site কুকি ও সাধারণ ফর্ম পোস্ট এটি পার হয়। টোকেন, গেট ও অনুমোদন যাচাই করুন।
অ্যাডমিন ইন্টারফেস admin.example.com-এ সরানো সত্যিকারের উন্নতি: এটি অ্যাডমিন কুকি জনসাধারণের পৃষ্ঠা থেকে দূরে রাখে, দুই অ্যাপ্লিকেশনকে আলাদা ক্যাশ দেয় এবং একটি হোস্টনেমে কঠোর নেটওয়ার্ক নীতি প্রয়োগ করতে দেয়। কিন্তু এটি CSRF নিয়ন্ত্রণ নয়, এবং জনসাধারণের সাইটের কোড লগইন করা অ্যাডমিনের জন্য খোলা রাখা নিরাপদ করে না। বিচ্ছেদ ব্রাউজার যা সীমানা মনে করে তা বদলায়, সার্ভার যা যাচাই করে তা নয়, তাই কাজটি শেষ বলার আগে এই চারটি পরীক্ষা করুন।
অরিজিন ও সাইটকে দুটি আলাদা শব্দ হিসেবে পড়ুন
অরিজিন মানে স্কিম, হোস্ট ও পোর্ট, তাই https://www.example.com এবং https://admin.example.com আলাদা অরিজিন। সাইট, SameSite অর্থে, স্কিম যোগ নিবন্ধনযোগ্য ডোমেইন, তাই ওই দুই হোস্টনেম সাধারণত একই সাইট। এই পার্থক্যই পুরো ফাঁদ: SameSite অ্যাট্রিবিউট ভগ্নী সাবডোমেইনের মধ্যে সাহায্য করবে না, কারণ ব্রাউজার অনুরোধটিকে সাইট-পার বলেই ধরে না। অ্যাডমিন ইন্টারফেস সত্যিই আলাদা নিবন্ধনযোগ্য ডোমেইনে, যেমন admin-example.net, ঘুরিয়ে দিন, তখন অনুরোধটি সত্যিই সাইট-পার হয়, আর সেখানেই SameSite=Lax বা Strict নির্ভরযোগ্য কাজ শুরু করে।
যুক্তি না করে ব্রাউজারে এটি পরীক্ষা করুন।
জনসাধারণের সাইট লোড করুন, ডেভেলপার টুল খুলুন, এবং অ্যাডমিন হোস্টের দিকে যাওয়া অনুরোধে ব্রাউজার কোন কুকি যুক্ত করে দেখুন। কুকিতে Domain অ্যাট্রিবিউট না থাকলে তা কেবল-হোস্ট এবং নিজের হোস্টনেমে থাকে; যদি Domain=example.com থাকে তবে তা প্রতিটি ভগ্নীর কাছে যায়, এবং নতুন সাবডোমেইন ওই কুকির জন্য কিছুই দেয়নি।
প্রতিক্রিয়া পড়া ও অনুরোধ পাঠানো আলাদা করুন
একই-অরিজিন নীতি অরিজিনের মধ্যে প্রতিক্রিয়া পড়া সীমিত করে। এটি অনুরোধ পাঠানো থামায় না, এবং ব্রাউজার ইতিমধ্যে ধরে রাখা প্রমাণপত্র ফর্ম পোস্টে বহন করা ঠেকায় না। সাধারণ অনুরোধ, ফর্ম কনটেন্ট-টাইপ বা সাধারণ GET সহ, প্রি-ফ্লাইট ছাড়াই পৌঁছায়; CORS তখন ঠিক করে আহ্বানকারী স্ক্রিপ্ট উত্তরটি পড়তে পারবে কি না। CSRF পুরোপুরি পাঠানোর দিকে থাকে।
তাই সার্ভারের অবস্থা-পরিবর্তনকারী কাজের জন্য স্পষ্ট পরীক্ষা দরকার। সেশনের সঙ্গে বাঁধা সিঙ্ক্রোনাইজার টোকেন, বা সার্ভারে তুলনা করা ডাবল-সাবমিট কুকি, এই ক্ষেত্রটি ঢাকে; Origin বা Referer তুলনা দ্বিতীয় গেট হিসেবে যোগ করা মূল্যবান, কিন্তু একমাত্র নয়, কারণ প্রতিটি অনুরোধ হেডার বহন করে না এবং প্রতিটি প্রক্সি তা সংরক্ষণ করে না। OWASP-এর CSRF প্রতিরোধ নির্দেশিকা SameSite-কে কয়েকটি স্তরের একটি হিসেবে ধরে, ঠিক এই কারণে।
নেটওয়ার্ক গেট আসলে কী প্রমাণ করে তা ঠিক করুন
অ্যাডমিন হোস্টের সামনে VPN এক্সিট অনুমোদন তালিকা ভালো নিয়ন্ত্রণ ও দুর্বল পরিচয় দাবি। এটি প্রমাণ করে অনুরোধ VPN যে ঠিকানা দেয় সেখান থেকে এসেছে, যা ওই এক্সিটের সবাই ভাগ করতে পারে, এবং এর পিছনে কোন ব্যক্তি বা ডিভাইস তা কিছুই বলে না। এটিকে প্রবেশ ফিল্টার হিসেবে ধরুন, প্রমাণীকরণ হিসেবে নয়।
অনুরোধ-স্তরের পরীক্ষা থেকে এটিকে স্বাধীন রাখুন। যদি অনুমোদন তালিকা আক্রমণকারী ও অবস্থা-পরিবর্তনকারী এন্ডপয়েন্টের মধ্যে একমাত্র বস্তু হয়, তবে একটি ভুল কনফিগার করা রুট, একটি split-tunnel ক্লায়েন্ট বা একটি ধার করা ল্যাপটপ নিয়ন্ত্রণটি সম্পূর্ণ সরিয়ে দেয়।
প্রত্যাশিত পরিসরের বাইরের প্রত্যাখ্যানও লগ করুন। সেগুলোর বিস্ফোরণই সবচেয়ে কাজের সংকেত যে কেউ এইমাত্র বানানো সীমানা যাচাই করছে, আর নীরবতা সংকেত যে ফিল্টারে কিছুই পৌঁছায় না।
কুকি, সাইন-ইন ও অনুমোদন স্পষ্ট রাখুন
কুকির পরিসর ফলাফলের অধিকাংশ ঠিক করে। প্যারেন্ট-ডোমেইন কুকি অ্যাডমিন হোস্টে পাঠানো হয়, তাই জনসাধারণের সাইটে স্ক্রিপ্ট ইনজেকশন প্রশাসকের সেশন দিয়ে কাজ করতে পারে; কেবল-হোস্ট কুকি পারে না। কেবল-হোস্ট রূপটি বেছে নিন, Secure অ্যাট্রিবিউট যোগ করুন, এবং প্ল্যাটফর্ম সমর্থন করলে __Host- উপসর্গ ব্যবহার করুন, কারণ ওই উপসর্গ Secure, Path=/ এবং Domain অ্যাট্রিবিউট না থাকা দাবি করে। কুকি জার নয়, প্রতিক্রিয়া হেডার পড়ুন: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax, Domain অ্যাট্রিবিউট ছাড়া। ব্রাউজার Domain থাকা __Host- কুকি ফেলে দেয়, তাই ভগ্নী হোস্টে এখনো দেখা যাওয়া কুকি প্রমাণ যে উপসর্গ কখনো প্রয়োগ হয়নি।
তারপর অনুমোদন সার্ভারে, প্রতিটি অনুরোধে, প্রতিটি অ্যাডমিন এন্ডপয়েন্টে রাখুন, কেবল লগইনে নয়। অনুমোদিত নেটওয়ার্ক থেকে আসা অনুরোধকেও এখনো প্রমাণিত হতে হবে এবং যে কাজ চায় তার জন্য অনুমোদিত হতে হবে; হোস্টনেম কোনো কর্তা নয়। যদি জনসাধারণের ও অ্যাডমিন অ্যাপ্লিকেশন সাইন-ইন প্রবাহ বা সেশন ভান্ডার ভাগ করে, সেই সম্পর্ক লিখে রাখুন, কারণ জনসাধারণের সাইটের ত্রুটি থেকে অ্যাডমিন কাজে পৌঁছানোর সবচেয়ে ছোট পথ সেটিই।
বিভাজনের পরে সীমানা আবার যাচাই করুন
নেতিবাচক পরীক্ষা চালান, কেবল সুখের পথ নয়: টোকেন ছাড়া সাইট-পার ফর্ম পোস্ট প্রত্যাখ্যাত হতে হবে, অন্য সেশনের টোকেন প্রত্যাখ্যাত হতে হবে, এবং কোনো GET অবস্থা বদলাবে না। ডেভেলপার টুলে কুকি অ্যাট্রিবিউট যাচাই করুন, অমিল থাকা অনুরোধে Origin পরীক্ষা জ্বলে কি না নিশ্চিত করুন, এবং VPN পরিসরের বাইরে থেকে অ্যাডমিন হোস্ট চেষ্টা করে ফিল্টার কাজ করতে দেখুন।
এর কিছুই অ্যাডমিন অ্যাপ্লিকেশনের ভেতরের XSS ত্রুটি সরায় না। আলাদা হোস্টনেম ব্রাউজার-পক্ষের বিচ্ছিন্নতা সীমানা যার সত্যিকারের মূল্য আছে, এবং এটি অনিরাপদ কোড চালানো প্রতিরোধ বা সার্ভার-পক্ষের অনুরোধ সুরক্ষার বিকল্প নয়। বিভাজনের পরে তালিকাটি দেখতে যতটা লাগে তার চেয়ে ছোট: আলাদা অরিজিন, কেবল-হোস্ট কুকি, প্রতিটি পরিবর্তনে টোকেন, পরিচয় হিসেবে অবিশ্বাস্য প্রবেশ ফিল্টার, এবং প্রতি অনুরোধে নির্ধারিত অনুমোদন।