পাঠ ৩৭ · ৫৭-এর মধ্যে · মডিউল ৯

স্ট্যাটিক বনাম ডাইনামিক অ্যানালাইসিস (SAST/DAST)

Static vs dynamic analysis (SAST/DAST)
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • SAST ও DAST-এর সংজ্ঞা এবং এই দুটো ঠিক কীভাবে আলাদা
  • প্রতিটি পদ্ধতির শক্তি ও সীমাবদ্ধতা — কোনটা কী ধরনের সমস্যা ধরতে পারে, কোনটা পারে না
  • বাস্তব ইন্ডাস্ট্রি টুলের সাধারণ, সুপরিচিত বৈশিষ্ট্য (সঠিক API সিনট্যাক্স আবিষ্কার না করে)
  • একটি সত্যিকারের, চলমান SAST-স্টাইল প্যাটার্ন স্ক্যানার — জেনুইন স্ট্রিং লজিক দিয়ে ঝুঁকিপূর্ণ কোড শনাক্ত

১ · SAST — কোড না চালিয়ে বিশ্লেষণ

SASTStatic Application Security Testingসোর্স কোড (বা কম্পাইল করা বাইটকোড) সরাসরি বিশ্লেষণ করে ঝুঁকিপূর্ণ প্যাটার্ন খোঁজা, কোড আদৌ না চালিয়েই — অনেকটা একজন অভিজ্ঞ রিভিউয়ার কোড পড়ে সন্দেহজনক লাইন চিহ্নিত করার মতো, কিন্তু স্বয়ংক্রিয়ভাবে। SAST টুল সোর্স কোড পড়ে এমন প্যাটার্ন খোঁজে যা সাধারণত সমস্যাযুক্ত — যেমন সরাসরি সিস্টেম কমান্ড এক্সিকিউট করা, ইউজার ইনপুট সরাসরি একটি কমান্ড বা কোয়েরি স্ট্রিং-এ জোড়া (concatenate) দেওয়া, বা হার্ডকোড করা সিক্রেট। এর বড় সুবিধা: এটি কোড লেখার সময়েই চালানো যায় (IDE-তে বা CI পাইপলাইনে), অ্যাপ্লিকেশন ডিপ্লয় করার প্রয়োজনও পড়ে না।

২ · DAST — চলমান অ্যাপ্লিকেশনকে বাইরে থেকে টেস্ট করা

DASTDynamic Application Security Testingএকটি চলমান অ্যাপ্লিকেশনের সাথে বাইরে থেকে ইন্টারঅ্যাক্ট করে (HTTP রিকোয়েস্ট পাঠিয়ে) দুর্বলতা খোঁজা — সোর্স কোড না দেখেই, ঠিক যেভাবে একজন বহিরাগত ব্যবহারকারী বা অ্যাটাকার অ্যাপ্লিকেশনটি দেখে। DAST টুল সোর্স কোড দেখে না — এটি প্রকৃতপক্ষে অ্যাপ্লিকেশনটি ডিপ্লয় করা অবস্থায় (সাধারণত একটি স্টেজিং এনভায়রনমেন্টে) বিভিন্ন রিকোয়েস্ট পাঠিয়ে দেখে সার্ভার কীভাবে সাড়া দেয়। এর সুবিধা: এটি এমন সমস্যা ধরতে পারে যা শুধু কোড পড়ে বোঝা যায় না — যেমন সার্ভার মিসকনফিগারেশন, ভুল HTTP হেডার, বা রানটাইম এনভায়রনমেন্টের সমস্যা।

সোর্স কোড (না চালিয়ে) SAST টুল প্যাটার্ন খোঁজে চলমান অ্যাপ্লিকেশন DAST টুল বাইরে থেকে রিকোয়েস্ট পাঠায় দুটোই CI/CD পাইপলাইনে পরিপূরক হিসেবে চালানো হয় (M9/L40)
SAST দ্রুত, কোড লেখার সময়েই ফিডব্যাক দেয়; DAST ধীর কিন্তু বাস্তব রানটাইম আচরণ পরীক্ষা করে — একটি ব্যাপক সিকিউরিটি টেস্টিং কৌশলে দুটোই প্রয়োজন।
SAST-এর শক্তি
কোড লেখার সময়েই দ্রুত ফিডব্যাক, ডিপ্লয়মেন্টের প্রয়োজন নেই, প্রতিটি কোড পাথ পরীক্ষা করতে পারে (এমনকি যে পাথ কখনো এক্সিকিউট হয়নি)।
SAST-এর সীমাবদ্ধতা
ফলস পজিটিভ বেশি হতে পারে (প্যাটার্ন মিলে গেলেও বাস্তবে ঝুঁকিপূর্ণ নাও হতে পারে), এবং রানটাইম/কনফিগারেশন সমস্যা ধরতে পারে না।
DAST-এর শক্তি
প্রকৃত রানটাইম আচরণ, সার্ভার কনফিগারেশন, এবং একাধিক কম্পোনেন্টের মধ্যকার ইন্টারঅ্যাকশন থেকে উদ্ভূত সমস্যা ধরতে পারে।
DAST-এর সীমাবদ্ধতা
ধীরগতির, একটি ডিপ্লয় করা এনভায়রনমেন্ট দরকার, এবং শুধু সেই কোড পাথ পরীক্ষা করে যা টেস্টের সময় প্রকৃতপক্ষে ট্রিগার হয়েছে।
বাস্তব টুলের নাম (সাধারণ বৈশিষ্ট্য, সঠিক API নয়)

ইন্ডাস্ট্রিতে SonarQube-এর মতো টুল সাধারণত SAST-স্টাইল স্ট্যাটিক কোড অ্যানালাইসিসের জন্য পরিচিত (কোড কোয়ালিটি ও সিকিউরিটি প্যাটার্ন উভয়ের জন্য), যেখানে OWASP ZAP-এর মতো টুল DAST-স্টাইল — একটি চলমান ওয়েব অ্যাপ্লিকেশনে স্বয়ংক্রিয়ভাবে বিভিন্ন রিকোয়েস্ট পাঠিয়ে দুর্বলতা খোঁজে। এই পাঠের কোড এই টুলগুলোর প্রকৃত API নয় — শুধু SAST-এর অন্তর্নিহিত ধারণা (প্যাটার্ন-ম্যাচিং) একটি সরল, স্বনির্ভর সংস্করণে দেখানো হলো।

৩ · একটি সত্যিকারের SAST-স্টাইল স্ক্যানার

নিচের কোড সেলে scan_source ফাংশনটি কয়েকটি সিন্থেটিক "সোর্স কোড" স্ট্রিং বিশ্লেষণ করে — os.system( কল, eval( ব্যবহার, এবং SQL কীওয়ার্ডের সাথে স্ট্রিং কনক্যাটেনেশন (+) — এই তিনটি সাধারণ ঝুঁকিপূর্ণ প্যাটার্ন সত্যিকারের সাবস্ট্রিং/লাইন-ভিত্তিক চেক দিয়ে খুঁজে বের করে। ফলাফল প্রতিটি স্নিপেটের জন্য সত্যিকারের কম্পিউট করা, আগে থেকে লেখা নয়।

Python
SQL_KEYWORDS = ("select", "insert", "update", "delete")

def scan_source(code):
    """সরল SAST-স্টাইল স্ক্যানার — সোর্স কোড স্ট্রিং না চালিয়ে ঝুঁকিপূর্ণ প্যাটার্ন খোঁজে।"""
    flags = []

    if "os.system(" in code:
        flags.append("possible command injection via os.system(...)")

    if "eval(" in code:
        flags.append("use of eval() can execute arbitrary code")

    for line in code.splitlines():
        lowered = line.lower()
        if any(keyword in lowered for keyword in SQL_KEYWORDS) and "+" in line:
            flags.append(f"possible SQL injection via string concatenation: {line.strip()}")

    return flags

snippets = {
    "backup_script": '''
import os
def run_backup(filename):
    os.system("tar -cf backup.tar " + filename)
''',
    "unsafe_query": '''
def get_user(username):
    query = "SELECT * FROM users WHERE name = '" + username + "'"
    return db.execute(query)
''',
    "safe_query": '''
def get_user_safe(username):
    query = "SELECT * FROM users WHERE name = %s"
    return db.execute(query, (username,))
''',
    "eval_calculator": '''
def calculate(expr):
    return eval(expr)
''',
    "plain_add": '''
def add(a, b):
    return a + b
''',
}

for name, source in snippets.items():
    result = scan_source(source)
    status = "FLAGGED" if result else "clean"
    print(f"{name}: {status}")
    for flag in result:
        print(f"    - {flag}")

    
লক্ষ্য করুন safe_query ফ্ল্যাগ হয়নি — যদিও এর মধ্যে SELECT কীওয়ার্ড আছে, কিন্তু সেই লাইনে কোনো + কনক্যাটেনেশন নেই (এটি প্যারামিটারাইজড কোয়েরি ব্যবহার করছে, যা নিরাপদ প্র্যাকটিস)। বিপরীতে unsafe_query-তে একই লাইনে SELECT এবং + দুটোই আছে, তাই ফ্ল্যাগ হয়েছে। এটিই দেখায় স্ক্যানারটি সত্যিকারের প্যাটার্ন লজিক প্রয়োগ করছে — শুধু "SELECT শব্দ আছে কি না" চেক করলে safe_query-কেও ভুলভাবে ফ্ল্যাগ করে ফেলত (একটি ফলস পজিটিভ), যা SAST টুলের একটি পরিচিত সীমাবদ্ধতা।
মূল কথা · Key takeaway

SAST কোড পড়ে ঝুঁকিপূর্ণ প্যাটার্ন খোঁজে — দ্রুত, কিন্তু ফলস পজিটিভ/নেগেটিভের ঝুঁকি থাকে। DAST চলমান অ্যাপ্লিকেশনকে বাইরে থেকে যাচাই করে — বাস্তবসম্মত, কিন্তু ধীর ও শুধু পরীক্ষিত পাথ কভার করে। একটি পরিপক্ব সিকিউরিটি টেস্টিং কৌশল দুটোই ব্যবহার করে, ভিন্ন ধাপে (M9/L40-এ SDLC-তে কোথায় কোনটা ফিট করে তা বিস্তারিত)।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ একটি বাগ যা শুধু নির্দিষ্ট সার্ভার কনফিগারেশনে (যেমন একটি এক্সপোজড ডিবাগ এন্ডপয়েন্ট) দেখা দেয়, SAST নাকি DAST কোনটি এটি ধরার সম্ভাবনা বেশি, এবং কেন?

DAST — কারণ SAST শুধু সোর্স কোড দেখে, সার্ভারের প্রকৃত রানটাইম কনফিগারেশন (কোন এন্ডপয়েন্ট আসলে এক্সপোজড, কোন হেডার সেট করা আছে) দেখতে পায় না। DAST চলমান অ্যাপ্লিকেশনের সাথে সরাসরি ইন্টারঅ্যাক্ট করে বলে এই ধরনের কনফিগারেশন-নির্ভর সমস্যা ধরতে পারে।

প্র ০২ উপরের কোড সেলে scan_source-এর SQL-ইনজেকশন চেক শুধু একই লাইনে কীওয়ার্ড ও + খোঁজে, পুরো ফাইলে নয়। এতে কী সীমাবদ্ধতা থাকতে পারে?

যদি কোনো কোয়েরি একাধিক লাইনে ভাগ করে লেখা হয় (যেমন একটি ভেরিয়েবলে ধাপে ধাপে স্ট্রিং জোড়া দেওয়া, তারপর একটি ভিন্ন লাইনে সেটি ব্যবহার করা), তাহলে এই সরল লাইন-ভিত্তিক চেক সেটি ধরতে পারবে না — একটি ফলস নেগেটিভ। বাস্তব SAST টুল সম্পূর্ণ কোড ফ্লো ট্র্যাক করে (ডেটা-ফ্লো অ্যানালাইসিস) এই সীমাবদ্ধতা কাটিয়ে ওঠে, যা এই সরলীকৃত ডেমোর চেয়ে অনেক বেশি জটিল।

প্র ০৩ একটি টিমের যদি সীমিত সময় থাকে এবং একটি নতুন ফিচার রিলিজের আগে শুধু একটি পদ্ধতি বেছে নিতে হয় — SAST নাকি DAST — কোনটি বেছে নেওয়া বেশি যুক্তিসঙ্গত হতে পারে, এবং কেন এটি একটি সমঝোতা?

এটি প্রেক্ষাপট-নির্ভর, কিন্তু সাধারণত SAST দ্রুত ও সস্তা হওয়ায় CI পাইপলাইনে প্রতিটি কমিটে চালানো সহজ, তাই ন্যূনতম কভারেজ হিসেবে এটি প্রায়ই প্রথম পছন্দ। তবে এটি একটি সমঝোতা — DAST ছাড়া রানটাইম/ কনফিগারেশন-নির্ভর সমস্যা অধরা থেকে যাবে। বাস্তবে বেশিরভাগ পরিপক্ব টিম দুটোই ব্যবহার করে, ভিন্ন ধাপে (M9/L40-এ বিস্তারিত)।

অনুশীলন

  1. চিন্তা করুন: scan_source-এ আরও কোন কোন ঝুঁকিপূর্ণ প্যাটার্ন যোগ করা যেতে পারে বলে আপনার মনে হয়? (হিন্ট: হার্ডকোড করা পাসওয়ার্ড/API-কী স্ট্রিং, অথবা subprocess.call একটি শেল স্ট্রিং সহ)

    যুক্তিসঙ্গত সংযোজন: "password = \"" বা "api_key = \""-এর মতো প্যাটার্ন হার্ডকোড করা সিক্রেট শনাক্ত করতে পারে; subprocess.call( সহ shell=True উপস্থিতি os.system-এর মতোই কমান্ড ইনজেকশনের ঝুঁকি নির্দেশ করতে পারে। বাস্তব SAST টুল এমন ডজন-ডজন প্যাটার্নের একটি নিয়মিত-আপডেট হওয়া তালিকা রক্ষণাবেক্ষণ করে।

  2. পরীক্ষা করুন: উপরের কোড সেলে snippets-এ একটি নতুন এন্ট্রি যোগ করুন যাতে একটি লাইনে "DELETE FROM logs WHERE id = " + str(log_id) থাকে, তারপর Run চেপে দেখুন scan_source এটি ফ্ল্যাগ করে কি না।

    হ্যাঁ, ফ্ল্যাগ হবে — কারণ সেই লাইনে "delete" কীওয়ার্ড (লোয়ারকেসে মিলিয়ে) এবং + কনক্যাটেনেশন দুটোই উপস্থিত, তাই scan_source-এর SQL-ইনজেকশন চেকের শর্ত পূরণ হয়ে যায় এবং সেই লাইনটি "possible SQL injection via string concatenation" হিসেবে রিপোর্ট হবে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ ইনপুট ভ্যালিডেশন, অথেন্টিকেশন/অথোরাইজেশন টেস্টিং ও SDLC-তে সিকিউরিটি — এই মডিউলের বাকি পাঠগুলো পরবর্তী।
  • 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 — সব এক জায়গায়।
আগের পাঠ
সিকিউরিটি টেস্টিং ফান্ডামেন্টাল