SDLC-তে সিকিউরিটি টেস্টিং
এই পাঠে যা শিখবেন
- কেন সিকিউরিটি টেস্টিং যত আগে সম্ভব শুরু করা উচিত, শুধু রিলিজের আগে নয়
- SDLC-এর প্রতিটি ধাপে কোন ধরনের সিকিউরিটি কার্যক্রম ফিট করে — একটি স্পষ্ট টাইমলাইন
- থ্রেট মডেলিং কী (উচ্চ-স্তরে) এবং এটি কেন ডিজাইন পর্যায়ে করা উচিত
- একটি সত্যিকারের CI/CD পাইপলাইন কোড ডেমো যেখানে একটি সিকিউরিটি-স্ক্যান স্টেজ ব্যর্থ হলে পরবর্তী স্টেজ স্কিপ হয়ে যায়
১ · কেন "শেষে টেস্ট করা" যথেষ্ট নয়
অনেক টিমে সিকিউরিটি টেস্টিং ঐতিহাসিকভাবে রিলিজের ঠিক আগে একটি আলাদা, বিশেষায়িত ধাপ হিসেবে ঘটে — একটি "সিকিউরিটি অডিট" যা ডেভেলপমেন্ট প্রায় শেষ হয়ে যাওয়ার পর চালানো হয়। সমস্যা হলো, এই পর্যায়ে একটি ডিজাইন-স্তরের দুর্বলতা (যেমন একটি ভুল অথোরাইজেশন মডেল) খুঁজে পাওয়া গেলে তা ঠিক করা অত্যন্ত ব্যয়বহুল — M1/L03-এ আলোচিত "ডিফেক্ট যত পরে ধরা পড়ে, খরচ তত বেশি" নীতি এখানে পুরোপুরি প্রযোজ্য। সমাধান হলো সিকিউরিটি চিন্তাভাবনাকে প্রতিটি ধাপে ছড়িয়ে দেওয়া — একেই বলা হয় সিকিউরিটি "শিফট-লেফট" করা (M12/L51-এ সাধারণ শিফট-লেফট-টেস্টিং দর্শন বিস্তারিতভাবে কভার করা হবে; এখানে তার সিকিউরিটি-নির্দিষ্ট প্রয়োগ)।
২ · SDLC জুড়ে সিকিউরিটি কার্যক্রমের টাইমলাইন
ডিজাইন পর্যায়ে "এই সিস্টেমে কী কী সম্ভাব্য অ্যাটাক পয়েন্ট আছে, এবং কোনটি সবচেয়ে ঝুঁকিপূর্ণ" প্রশ্ন করা — কোড লেখার আগেই, তাই ডিজাইনেই প্রতিরোধ যোগ করা যায়।
প্রতিটি কমিট/পুল-রিকোয়েস্টে স্বয়ংক্রিয়ভাবে চলে — দ্রুত, তাই ডেভেলপার তাৎক্ষণিক ফিডব্যাক পান (M9/L37)।
একটি স্টেজিং এনভায়রনমেন্টে ডিপ্লয় করা অ্যাপ্লিকেশনের বিরুদ্ধে চালানো হয় — কোড-স্তরের বাইরে রানটাইম সমস্যা ধরতে (M9/L37)।
বিশেষজ্ঞদের দ্বারা সাময়িকভাবে (যেমন প্রতি কোয়ার্টারে) পরিচালিত গভীর, ম্যানুয়াল টেস্টিং — স্বয়ংক্রিয় টুল যা মিস করে তা ধরার জন্য।
৩ · CI/CD পাইপলাইনে একটি সিকিউরিটি-স্ক্যান স্টেজ
M7-এ (টেস্ট অটোমেশন) এবং M12/L54-এ ব্যবহৃত CI/CD পাইপলাইন প্যাটার্নটি এখানেও প্রযোজ্য — শুধু একটি
security_scan স্টেজ যোগ করে। নিচের কোড সেলে দেখানো হয়েছে কীভাবে একটি ব্যর্থ সিকিউরিটি স্ক্যান
পুরো পাইপলাইনকে থামিয়ে দেয়, পরবর্তী স্টেজগুলো (যেমন ডিপ্লয়) স্কিপ করে দিয়ে — একটি স্বয়ংক্রিয় "গেট"।
def build_pipeline(security_scan_passes):
"""একটি CI/CD পাইপলাইন তৈরি করে — কোন স্টেজ কতবার কল হলো তা ট্র্যাক করার জন্য।"""
calls = []
def lint():
calls.append("lint")
return True
def unit_test():
calls.append("unit_test")
return True
def security_scan():
calls.append("security_scan")
return security_scan_passes
def integration_test():
calls.append("integration_test")
return True
def deploy():
calls.append("deploy")
return True
stages = [
("lint", lint),
("unit_test", unit_test),
("security_scan", security_scan),
("integration_test", integration_test),
("deploy", deploy),
]
return stages, calls
def run_pipeline(stages):
for name, stage_fn in stages:
ok = stage_fn()
if not ok:
print(f"✗ {name} FAILED -- pipeline stopped, remaining stages skipped")
return False
print(f"✓ {name} passed")
return True
print("--- Run 1: security_scan ব্যর্থ হয় (একটি ঝুঁকিপূর্ণ প্যাটার্ন পাওয়া গেছে) ---")
stages_1, calls_1 = build_pipeline(security_scan_passes=False)
run_pipeline(stages_1)
print(f"executed stages: {calls_1}")
assert calls_1 == ["lint", "unit_test", "security_scan"], "deploy/integration_test আসলেই স্কিপ হওয়া উচিত ছিল"
print("assert OK: integration_test ও deploy সত্যিকারেই স্কিপ হয়েছে\n")
print("--- Run 2: security_scan পাস করে (ইস্যু ঠিক করার পর) ---")
stages_2, calls_2 = build_pipeline(security_scan_passes=True)
run_pipeline(stages_2)
print(f"executed stages: {calls_2}")
assert calls_2 == ["lint", "unit_test", "security_scan", "integration_test", "deploy"]
print("assert OK: এবার সবগুলো স্টেজ পর্যন্ত পৌঁছেছে")
calls_1-এর দৈর্ঘ্য মাত্র ৩ — integration_test ও
deploy ফাংশন দুটো আদৌ কল হয়নি, যা calls তালিকায় তাদের অনুপস্থিতি
দিয়ে সত্যিকারেই প্রমাণিত (হার্ডকোড করা দাবি নয়)। এটিই সিকিউরিটি স্ক্যানকে একটি প্রকৃত "গেট" বানায় — একটি
ব্যর্থ স্ক্যান কোডকে প্রোডাকশনে পৌঁছাতে বাধা দেয়, ম্যানুয়ালি মনে রাখার উপর নির্ভর না করে।
সিকিউরিটি টেস্টিং সবচেয়ে কার্যকর হয় যখন এটি একটি একক শেষ-পর্যায়ের চেক নয়, বরং ডিজাইন থেকে প্রোডাকশন পর্যন্ত পুরো SDLC জুড়ে বিতরণ করা কার্যক্রমের একটি সেট — প্রতিটি ধাপে উপযুক্ত টুল ও কৌশল প্রয়োগ করে। এটিই M9-এর সবগুলো পাঠকে (L36-L39) একটি সুসংগত সময়রেখায় একত্রিত করে, এবং M12/L51-এর সাধারণ শিফট-লেফট দর্শনের একটি কংক্রিট, সিকিউরিটি-নির্দিষ্ট উদাহরণ।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ থ্রেট মডেলিং কোডিং শুরুর আগে, ডিজাইন পর্যায়ে করা হয় কেন? কোডিং-এর পরে করলে কী হারানো যায়?
ডিজাইন পর্যায়ে থ্রেট মডেলিং করলে সম্ভাব্য দুর্বলতাগুলো এমনভাবে চিহ্নিত করা যায় যাতে স্থাপত্যগত সিদ্ধান্ত (যেমন কোন ডেটা কীভাবে সংরক্ষিত হবে, কোন কম্পোনেন্ট কোনটির উপর বিশ্বাস করবে) সেই ঝুঁকিগুলো মাথায় রেখেই নেওয়া যায়। কোডিং-এর পরে করলে, একটি মৌলিক স্থাপত্যগত দুর্বলতা খুঁজে পেলে তা ঠিক করতে বড় অংশের কোড পুনর্লিখন লাগতে পারে — M1/L03-এর খরচ-বক্ররেখার একটি সরাসরি উদাহরণ।
প্র ০২ স্বয়ংক্রিয় SAST/DAST থাকা সত্ত্বেও কেন পর্যায়ক্রমিক ম্যানুয়াল পেনিট্রেশন টেস্টিং এখনও প্রয়োজন?
স্বয়ংক্রিয় টুল পূর্বনির্ধারিত প্যাটার্ন ও পরিচিত চেক অনুসরণ করে — এগুলো সৃজনশীল, বহু-ধাপের, বা ব্যবসায়িক-লজিক-নির্ভর অ্যাটাক চেইন (যা কোনো একক প্যাটার্নে ফিট করে না) সহজে ধরতে পারে না। একজন দক্ষ মানব পেন-টেস্টার সিস্টেমটিকে সামগ্রিকভাবে দেখে অপ্রত্যাশিত সংমিশ্রণ খুঁজে বের করতে পারেন, যা M10/L44-এর এক্সপ্লোরেটরি টেস্টিং-এর ধারণার সাথে মিল রাখে।
প্র ০৩
উপরের কোড সেলে যদি security_scan স্টেজটি stages তালিকায়
deploy-এর পরে রাখা হতো, তাহলে Run 1-এর ফলাফল কীভাবে ভিন্ন হতো?
তাহলে deploy স্টেজটি সিকিউরিটি স্ক্যানের ফলাফল জানার আগেই কল হয়ে যেত এবং
calls-এ যুক্ত হয়ে যেত — অর্থাৎ ঝুঁকিপূর্ণ কোড প্রোডাকশনে ডিপ্লয় হয়ে যাওয়ার পরে সিকিউরিটি
স্ক্যান ব্যর্থ হওয়ার খবর আসত, যা অনেক দেরি। স্টেজের ক্রম নিজেই একটি গুরুত্বপূর্ণ ডিজাইন সিদ্ধান্ত —
গেটকিপিং স্টেজগুলো সবসময় যা তারা রক্ষা করছে তার আগে থাকা উচিত।
অনুশীলন
-
চিন্তা করুন: এই পাঠের টাইমলাইনে "কোড রিভিউ"-কে সিকিউরিটি কার্যক্রম হিসেবে অন্তর্ভুক্ত করা
হয়েছে। একটি পিয়ার কোড রিভিউ কীভাবে একটি সিকিউরিটি বাগ ধরতে সাহায্য করতে পারে, যা SAST নাও ধরতে পারে?
একজন মানব রিভিউয়ার ব্যবসায়িক লজিকের প্রেক্ষাপট বুঝতে পারেন — যেমন "এই ফাংশনটি প্যাটার্ন হিসেবে নিরাপদ দেখতে হলেও, এটি ভুল অর্ডারে কল হচ্ছে বলে একজন ব্যবহারকারী অথোরাইজেশন চেক এড়িয়ে যেতে পারবেন"। এই ধরনের প্রেক্ষাপট-নির্ভর যুক্তি স্বয়ংক্রিয় প্যাটার্ন-ম্যাচিং টুলের ক্ষমতার বাইরে, যা M9/L37-এ SAST-এর সীমাবদ্ধতা হিসেবে আলোচিত হয়েছিল।
-
পরীক্ষা করুন: উপরের কোড সেলে
build_pipeline-এunit_test-এর পরে একটি নতুন স্টেজdast_scanযোগ করুন (যা সবসময়Trueরিটার্ন করে), এবংsecurity_scan_passes=Falseদিয়ে আবার Run করে দেখুনcallsতালিকায়dast_scanআসে কি না।যদি
dast_scanস্টেজটিsecurity_scan-এর পরে রাখা হয় (তালিকায় তার ক্রম অনুযায়ী), তাহলেsecurity_scan_passes=False-এর ক্ষেত্রে এটি একদমই কল হবে না — কারণ পাইপলাইনsecurity_scan-এই থেমে যায়। এই পরীক্ষাটি নিশ্চিত করে যে পাইপলাইনের early-stop লজিক নতুন যোগ করা স্টেজের জন্যও সমানভাবে কাজ করে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাডভান্সড টেস্টিং টেকনিক (প্রপার্টি-বেসড, মিউটেশন, ফাজ) — M10-এর পরবর্তী পাঠগুলো এই মডিউলের পরে।
- Cybersecurity কোর্স সহোদর কোর্স থ্রেট মডেলিং ও নির্দিষ্ট অ্যাটাক ভেক্টরের টেকনিক্যাল গভীরতা সেই কোর্সে কভার করা হয়েছে।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks, Mobile App Development, Ethics in Computing & AI Safety ও Software Testing & Quality Assurance — সব এক জায়গায়।