معصومه کوهستانی
معصومه کوهستانی
خواندن ۷ دقیقه·۳ سال پیش

Static Code Analysis

تحلیل استاتیک کد
تحلیل استاتیک کد

مقدمه

تحلیل استاتیک کد (Static Code Analysis) یا تحلیل سورس کد (Source Code Analysis)، کشف خطاها و مشکلات سورس کد برنامه و تحلیل یک نرم افزار بدون اجرای آن در مرحله‌‌ی پیاده‌سازی کد است، برخلاف تحلیل پویای کد که به تحلیل نرم افزار با اجرای آن می‌پردازد. تحلیل استاتیک کد به صورت خودکار و با یک سری ابزار بر روی یک ورژن از سورس کد به منظور کشف آسیب‌پذیری‌های احتمالی کد استاتیک (کدی که در حال اجرا شدن نیست) با استفاده از یک سری تکنیک‌ها انجام می‌شود. در حالیکه به تحلیل کد توسط انسان، بازبینی کد (تست جعبه سفید یا white-box testing) گفته می‌شود. تحلیل استاتیک کد بخشی از بازبینی کد است. این تحلیل به عبارتی همان بازبینی کد اتوماتیک است.

یکی از علل پیدایش تحلیل استاتیک کد دقت کم بازبینی کد توسط افراد است. بازبینی کد نیاز به خواندن کد، پیدا کردن فرد مناسب برای بررسی کد، بازبینی مجدد پس از اعمال تغییرات و غیره دارد. اگر نیاز داشته باشیم که کد به صورت مداوم با هر تغییر بررسی شود چه؟ این کار برای افراد هزینه بر و زمان بر است. اینجاست که می‌توانیم از تحلیل استاتیک کد استفاده کنیم. البته این تحلیل نمی‌تواند جایگزین بازبینی کد شود و ما هم‌چنان به بررسی‌های دستی نیاز داریم.


این نوع تحلیل نسبت بررسی خط به خط کد حرف بیشتری برای گفتن دارد. تحلیل استاتیک کد می‌تواند منجر به کشف خطاهای احتمالی کد یا بررسی انطباق رفتار برنامه با استانداردهای تعیین شده، شود. در سیستم‌های حساس و حیاتی و سیستم‌های نهفته‌ی بیدرنگ هم از این نوع تحلیل برای کشف کدهای آسیب‌پذیر احتمالی به دلیل حساسیت نتایج ارائه شده، استفاده می‌شود. از جمله‌ی این سیستم‌ها می‌توان نرم‌افزارهای پزشکی، نرم‌افزارهای هسته‌ای، نیروهای هوایی و ماشین‌های اتوماسیون را نام برد که برای مثال وزارت غذا و داروی ایالات متحده‌ی آمریکا (FDA) در نرم‌افزارهای پزشکی و دفتر مقررات هسته‌ای بریتانیا (ONR) در نرم‌افزارهای هسته‌ای تحلیل استاتیک کد را مورد استفاده قرار می‌دهد. طبق آمار ارائه شده در سال‌های ۲۰۱۰ و ۲۰۱۲، حرکت برنامه نویسان به سمت استفاده از تحلیل استاتیک کد دیده می‌شود. [1]

ابزارهای تحلیل استاتیک کد به صورت خودکار نقص‌های امنیتی را با احتمال بالای درستی کشف می‌کند. این ابزارها به تحلیلگران کمک می‌کند تا نقص‌های کد را پیدا کرده و تعداد نقص‌های پیدا نشده را به صفر نزدیک کنند. برخی ابزارها وارد IDE شده اند تا در هنگام کدنویسی نقص‌های احتمالی را پیدا کنند که باعث فیدبک سریع به برنامه‌نویس در حین کدنویسی و نه بعد از نوشتن کد می‌شود. این فیدبک سریع بسیار بهتر از این است که برخی نقص‌ها مدت‌ها بعد از اتمام توسعه‌ی کد پیدا شوند.[3]

این ابزارهای به دنبال نقص‌های کدنویسی، درهای پشتی برنامه و دیگر کدهای مخرب که به هکرها دسترسی به داده‌های مهم شرکت‌ها یا اطلاعات مشتریان می‌دهد، هستند. این ابزارها در واقع امنیت و عملکرد کد در زمانی که در حال اجرا نیست را در زمان پیاده‌سازی (قبل از تست واحد) بررسی می‌کنند که باعث کشف باگ‌های احتمالی قبل از ورود به مرحله‌ی production می‌شود. این کار باعث افزایش سرعت در پیاده‌سازی به دلیل راحتتر و کم هزینه‌تر کردن رفع باگ‌ها برای برنامه‌نویسان در زمان کدنویسی، می‌شود. [5]

کارهایی که یک تحلیلگر استاتیک کد انجام می‌دهد [4]

  • کشف خطاها در برنامه
  • پیشنهادهایی برای فرمت کد. برخی تحلیل‌گرهای استاتیک کد بررسی می‌کنند که کد شما با فرمت استاندارد ارايه شده توسط شرکت شما هم‌خوانی دارند یا خیر.
  • محاسبه‌ی متریک. معیارهای عددی مبنی بر کیفیت کد شما ارائه داده می‌شود.

سطوح تحلیل برنامه

گروه مدیریت اشیا (Object Management Group or OMG) یک مطالعه در مورد انواع تحلیل‌های نرم‌افزار ضروری برای اندازه‌گیری کیفیت نرم‌افزار منتشر کرده است. این مستند سه سطح تحلیل نرم‌افزار را اینگونه توضیح می‌دهد [1] :

  • سطح واحد (Unit Level): تحلیلی که درون یک برنامه‌ی خاص یا یک متد خاص اتفاق می‌افتد و با دیگر قسمت‌های برنامه کاری ندارد.
  • سطح تکنولوژی (Technology Level): تحلیلی که ارتباط بین واحد ها را با هدف کشف مشکلات و دوری از جواب‌های کاذب در نظر می‌گیرد.
  • سطح سیستم (System Level): تحلیلی که ارتباط بین واحدها را مستقل از تکنولوژی و زبان در نظر میگیرد.

سطح دیگری از تحلیل نرم افزار هم وجود دارد:

  • سطح کسب‌وکار/ماموریت (Mission/Business Level): تحلیلی که سیاست‌ها، قوانین و فرآیندهای کسب‌وکار را که در برنامه پیاده‌سازی شده‌اند را هم در نظر می‌گیرد. این موارد بدون در نظر گفتن تکنولوژی و زبان پیاده‌سازی شده‌اند.

روش‌های رسمی (Formal methods)

روش‌های رسمی که از روش‌های ریاضی استفاده می‌کنند بر تحلیل‌های نرم‌افزار اعمال می‌شود. با توجه به مساله‌ی توقف‌ (Halting Problem) می‌توان اثبات کرد که کشف تمامی خطاهای در زمان اجرای هر برنامه‌ای غیرقطعی است. هیچ روشی برای این کار وجود ندارد. ولی با این وجود می‌توان از راه‌حل‌های تقریبی استفاده کرد. [1] این تکنیک‌ها اغلب از تکنیک‌های کامپایلرها ایده گرفته‌اند. برخی از تکنیک‌های پیاده‌سازی تحلیل استاتیک رسمی شامل موارد زیر هستند:

  • تفسیر انتزاعی (Abstraction Interpretation)
  • تحلیل جریان داده (Data-flow Analysis): بررسی جریان داده‌ها در گراف طراحی شده از برنامه. به عبارتی در این نوع تحلیل به جمع‌آوری اطلاعات زمان اجرا درباره‌ی داده‌ها می‌پردازیم در حالیکه برنامه در حالت استاتیک (یعنی هنوز اجرا نشده است) قرار دارد. سه اصطلاح پرکاربرد در این روش: ۱. basic block یا همان کد ۲. تحلیل کنترل جریان یا همان جریان داده ۳. مسیر کنترل جریان یا همان مسیر‌هایی که داده‌ها در آن‌ها جریان دارند.
مثال یک Basic Block
مثال یک Basic Block

با استفاده از این بلاک‌ها یک گراف به نام Control Flow Graph ساخته می‌شود که گره‌ها‌ی آن همین بلاک‌ها هستند. یال‌ها هم مسیر‌های بین بلاک‌ها هستند.

CFG
CFG
  • منطق هور (Hoare Logic)
  • بررسی مدل (Model Checking): بررسی سیستم‌های دارای حالت‌های محدود
  • اجرای نمادین (Symbolic Execution): بررسی برنامه با نمادهای معادلِ عبارت‌های موجود در کد
  • تحلیل تینت (Taint Analysis): بررسی داده‌هایی که توسط کاربر تغییر کرده‌اند ولی چک نشده‌اند. اگر این داده‌ها بدون بررسی به پایان برسند به عنوان یک نقطه‌ی آسیب‌پذیر شناخته می‌شوند.
  • تحلیل لغوی (Lexical Analysis): این تحلیل سینتکس سورس کد را به توکن‌ تبدیل می‌کند تا سورس کد را انتزاعی کرده و تغییر آن را راحتتر نماید. برای مثال:

نقاط قوت [3] [4] [5]

  • مقیاس‌پذیری (قابلیت اجرا بر روی ‌برنامه‌های زیاد و به صورت مکرر)
  • احتمال قوی درست بودن نقص‌های کشف شده مانند سرریز بافر، SQL Injection و غیره.
  • سرعت بیشتر نسبت به تحلیل دستی توسط انسان‌ها، در نتیجه راحتی و هزینه‌ی کم
  • دقت بالا نسبت به تحلیل دستی توسط انسان‌ها
  • پوشش کامل کد
  • مستقل از کامپایلر. این ویژگی باعث کشف خطاها پس از تغییر کامپایلر می‌شود.
  • تشخیص سریع خطاهای مربوط به پرینت کردن خروجی و نتایج کپی/پیست کردن در کد

نقاط ضعف [3] [4]

  • کشف بسیاری از مشکلات امنیتی بسیار دشوار می‌باشد مانند مشکلات اعتبارسنجی، استفاده‌ی ناامن از کریپتوگرافی و غیره. هر چند این ابزارها در حال بهتر شدن در این زمینه هستند.
  • تعداد زیاد جواب‌های کاذب درست
  • عدم توانایی کشف مشکلات مربوط به تنظیمات چون در کد وجود ندارند.
  • دشواری اثبات آسیب‌پذیر بودن مشکل امنیتی کشف شده
  • دشواری کشف مشکل در کدهایی که قابل کامپایل شدن نیستند. تحلیلگران نمی‌توانند کد را کامپایل کنند چون کتابخانه‌های درست یا همه‌ی کد را ندارند.
  • عدم توانایی تشخیص نشت حافظه و خطاهای مربوط به همزمانی که این مشکل با تحلیل پویای کد قابل حل است.

محدودیت‌ها

  • False Positive

گاهی این ابزار مشکلاتی را گزارش می‌کنند که در واقع مشکل نیستند. دلیل این تشخیص اشتباه این است که ابزار در مورد یکپارچگی و امنیت داده‌ی در جریان شک دارد. این اتفاق اکثرا در کدهای متن بسته رخ می‌دهد چون بدون کد امکان بررسی جریان داده وجود ندارد. [3]

  • False Negative

گاهی این ابزار مشکلاتی را که در واقع مشکل هستند را گزارش نمی‌کنند. این اتفاق زمانی می‌افتد که اگر مشکل کشف شده از یک کامپوننت خارجی باشد یا ابزار دانشی راجع به محیط اجرا نداشته باشد یا به صورت امن تنظیم شده باشد. [3]

محدودیت‌های دیگری مانند تنظیمات نادرست، کتابخانه‌های نادرست و غیره نیز وجود دارد. [5]

معرفی ابزارها و فناوریهای متن‌باز [6]

ابزار‌های تحلیل‌گر کد متن‌باز و متن‌بسته‌ی زیادی وجود دارند و زبان‌های بسیاری را پشتیبانی می‌کنند.

  • SonarQube

این ابزار بیش از ۲۰ زبان برنامه نویسی را پشتیبانی می‌کند. گزارش‌هایی در مورد کدهای تکراری، استاندارد کد نویسی، پوشش کد، پیچیدگی کد، کامنت‌ها، باگ‌ها و مشکلات امنیتی ارائه می‌دهد. این ابزار می‌تواند گراف رسم کند و تاریخچه نگهدارد. قابلیت پشتیبانی از تکنولوژی‌هایی مانند maven، Ant، Gradle و غیره را نیز دارد. [7]

SonarQube
SonarQube
  • StyleCop

یک ابزار تحلیل‌گر کد متن‌باز است که توسط مایکروسافت ارائه شده است. این ابزار زبان‌ C#‌ را پشتیبانی می‌کند. یک سری قوانین تعریف شده مانند نامگذاری، ترتیب، خوانایی و غیره را بررسی می‌کند. به صورتی گرافیکی و یا کامند لاین ارائه شده است. [8]

StyleCop
StyleCop


طبق آمار ارائه شده در کتاب Code Complete از McConnell، رفع یک خطا در زمان تست ۱۰ برابر هزینه‌ی بیشتری از رفع آن در زمان نوشتن کد دارد [4]:

یکی از کاربردهای این ابزار آموزش به افراد تازه واردی که هنوز با قوانین کدنویسی شرکت آشنا نیستند، است.

بهترین راه برای تحلیل کد استفاده‌ی ترکیبی از تحلیل استاتیک و پویای کد است. تحلیل استاتیک با حذف بسیاری از مشکلات قبل از اجرا باعث تقویت کلی کد و افزایش کیفیت برنامه می‌شود. درحالیکه تحلیل پویا خطاهای زمان اجرا را که توسط روش‌های استاتیک قابل کشف را پیدا می‌کند. [5]


این مطلب، بخشی از تمرینهای درس معماری نرم‌افزار در دانشگاه شهیدبهشتی است.

مراجع

[1] https://en.wikipedia.org/wiki/Static_program_analysis

[2] https://fa.wikipedia.org/wiki/%D8%AA%D8%AD%D9%84%DB%8C%D9%84_%D8%A7%DB%8C%D8%B3%D8%AA%D8%A7%DB%8C_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87

[3] https://owasp.org/www-community/controls/Static_Code_Analysis

[4] https://pvs-studio.com/en/blog/terms/0046/

[5] https://www.whitehatsec.com/glossary/content/static-analysis

[6] https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

[7] https://en.wikipedia.org/wiki/SonarQube

[8] https://en.wikipedia.org/wiki/StyleCop

معماری_نرم_افزار_بهشتی
شاید از این پست‌ها خوشتان بیاید