تحلیل گر کد ایستا یا static analyzer ابزاری است که میتواند برخی از مشکلات کدنویسی را قبل از اجرای کد به صورت اتوماتیک پیدا کند. درست شبیه به Warning هایی که خود کامپایلر می دهد اما در ابزار تحلیل گر کد ایستا قدری عمیق تر این کار انجام می شود. از آن جایی که اکثر آسیب پذیری های کلیدی در سیستم های بحرانی ایمنی ( Safety-critical systems ) ناشی از کدنویسی و تست ضعیف نرم افزار می باشد، در این آموزش قصد داریم تا با یکی از معروفترین ابزارهای تحلیل گر کد ایستا یعنی cppcheck آشنا شویم و از آن در ایمن کردن کدنویسی خود استفاده کنیم.
کدنویسی امن چیست ؟
کدنویسی امن ( Secure coding ) روشی برای نوشتن کدهای یک نرم افزار است به گونهای که برنامه در برابر انواع آسیبپذیری، حمله یا هر چیزی که میتواند باعث آسیبرساندن به نرمافزار یا سیستم شود، محافظت میشود. در سیستم هایی بحرانی ایمنی ( Safety-critical systems ) که نرم افزار آن ها بایستی سال ها به صورت ایمن و بدون مشکل کار کنند این موضوع بسیار اهمیت دارد. سیستم هایی نظیر هواپیماها، خودروها، دستگاه های پزشکی، فضاپیما ها، قطارها، پروسه های کنترلی در صنعت نفت و گاز و پتروشیمی، آسانسورها و … در این گونه سیستم ها بایستی اصول کدنویسی امن رعایت شود در غیر این صورت ممکن است نرم افزار دچار مشکل شده و حادثه بوجود بیاید و منجر به ضررهای جانی یا مالی شدیدی شود.
از طریق تجزیه و تحلیل هزاران آسیبپذیری گزارش شده، متخصصان امنیتی کشف کردهاند که بیشتر آسیبپذیریها به دلیل خطاهای برنامهنویسی رایج هستند. با شناسایی شیوههای نادرست برنامهنویسی که منجر به خطا میشوند و آموزش توسعه دهندگان، سازمانها میتوانند اقدامات پیشگیرانه ای را جهت کاهش یا حذف آسیبپذیریهای نرمافزاری قبل از استقرار در محیطهای عملیاتی آنها را از بین ببرند. از همین رو سازمان های مختلف روی مواردی که منجر به نا امن شدن نرم افزار می شود کار کردند و استانداردهای مختلف در زمینه کدنویسی امن پدید آوردند.
استانداردهای مربوط به کدنویسی امن
صدها استاندارد مربوط به ایمنی وجود دارند که توسط سازمان های مختلف نوشته و توسعه داده شده اند. از میان همه آن ها استاندارد IEC 61508 که به ایمنی در سیستم های صنعتی مربوط می شود و پایه و اساس بسیاری از استانداردهای دیگر است. این استاندارد شامل اصولی است که منجر به ایمنی در صنعت می شود که به صورت ویژه در بخش 3 به ایمنی نرم افزار می پردازد. اما از نقطه نظر توسعه نرمافزار، با ارزشترین کمکهای IEC 61508، جداولی است که در ضمیمههای A و B بخش 3 آن است که هر کدام فهرستی از ابزارها و تکنیکهایی را برای هر مرحله از چرخه عمر توسعه نرم افزار در سه دسته بندی توصیه نشده، توصیه شده و اکیدا توصیه شده ارائه میکنند. برای اطلاعات بیشتر در مورد این استاندارد به مقاله زیر مراجعه نمایید:
آشنایی با گواهینامه SIL و آموزش استانداردهای IEC 61508 و IEC 61511
همچنین استاندارد ISO 26262 که استاندارد IEC 61508 را برای سیستم های داخلی خودرو اختصاصی کرده و گسترش می دهد بخشی برای ایمنی نرم افزار اختصاص داده شده است. همچنین استاندارد IEC 62304 که ایمنی نرم افزارهای حوزه پزشکی را پوشش می دهد. علاوه بر این ها استانداردهای دیگری نظیر IEC 29119 ( استاندارد تست نرم افزار ) و EN 50128 ( استاندارد راه آهن ) نیز وجود دارند. در کتاب “توسعه نرم افزارهای امبدد برای سیستم های بحرانی-ایمنی” موضوعات با اهمیت این استانداردها بیان شده است. این کتاب ارزشمند از طریق لینک زیر قابل دریافت است:
دانلود کتاب توسعه نرم افزارهای امبدد برای سیستم های بحرانی ایمنی
همچنین انجمن قابلیت اطمینان نرم افزار در صنعت موتور ( Motor Industry Software Reliability Association ) مجموعه ای از دستورالعمل های توسعه نرم افزار برای زبان برنامه نویسی C و ++C را با هدف تسهیل ایمنی کد، امنیت، قابلیت حمل و قابلیت اطمینان سیستم های تعبیه شده فراهم کرده است که آن هم جزو بهترین منابع در زمینه کدنویسی امن می باشد. برای دانلود این دستورالعمل به لینک زیر مراجعه نمایید:
دانلود دستورالعمل MISRA برای زبان های C و ++C در سیستم های بحرانی
از دیگر استانداردهای مهم مربوط به کدنویسی امن میتوان به استاندارد خودرویی AUTOSAR و CERT ( برای C و ++C و Java ) اشاره کرد.
راه های تشخیص نقاط ضعف نرم افزار
هر گونه خطا در تحلیل، طراحی یا پیاده سازی نرم افزار که سیستم را در مقابل حملات آسیب پذیر می نماید نقاط ضعف نرم افزار ( Software Weakness ) گویند. روشهای تشخیص نقاط ضعف نرم افزار از روی سورس کد عبارت است از :
تحلیل ایستا ( Static Analysis ) : در این روش، ارزیابی نقاط ضعف نرم افزار از طریق تکنیک های تحلیل سورس کد به صورت اتوماتیک انجام می گیرد. شرکت پژوهشی گارتنر استفاده از این روش را برای تولیدکنندگان نرم افزار ضروری می داند. مزیت این روش سرعت بالای جستجوی کد در برنامه های کاربردی بزرگ و تشخیص خطاهای خطرناکی همچون سرریز آرایه ها ( Buffer Overflow ) و نشت حافظه ( memory leaks ) می باشد. از معایب آن هم میتوان به امکان تشخیص اشتباه خطاها ( false-positive )، نیاز به تهیه لایسنس برای ورژن های کامل تر و عدم تشخیص خطاهای منطقی در کدنویسی می باشد.
تحلیل پویا ( Dynamic Analysis ) : در این روش، ارزیابی خطاها و نقاط ضعف نرم افزار از طریق تحلیل برنامه در حال اجرا صورت می گیرد. مزیت این روش دقت بالا در تشخیص خطاهای زمان اجرا و امکان تشخیص اشتباه خطاهای کمتر ( false-positive کمتر ) می باشد. از معایب این روش هم میتوان به کند شدن سیستم در برخی از روش های آن، نیاز به تهیه و یادگیری ابزارهای مناسب آن و توانایی تشخیص صرفا خطاهای هنگام اجرا اشاره کرد.
مرور دستی ( Manual Review ) : در این روش، سورس کد به صورت دستی توسط یک شخص/تیم جهت استخراج نقاط ضعف برنامه مورد ارزیابی قرار می گیرد. مزیت این روش توانایی تشخیص اشتباهات منطقی به دلیل استفاده از هوش و تجربه انسانی و همچنین امکان تشخیص اشتباه کمتر ( false-positive کمتر ) می باشد. اما از معایب این روش میتوان به زمان بر بودن پروسه تشخیص نقاط ضعف، عدم مقیاس پذیری برای برنامه های کاربردی بزرگ و عدم تشخیص آسیب پذیری های ناشی از ارتباطات بین کدها و برنامه ها می باشد.
آزمون واحد ( Unit test ) : در این روش، ارزیابی خطاها و نقاط ضعف نرم افزار از طریق پیاده سازی و اجرای آزمونهای برنامه نویسی صورت می گیرد. از مزیت های این روش میتوان به توانایی بالا در تشخیص خطاهای منطقی، امکان تشخیص اشتباه کم ( false-positive کم ) و امکان بررسی اکثریت مسیرهای برنامه اشاره کرد. همچنین معایب آن هم شامل زمان بر بودن پروسه تولید آزمون واحد، نیاز به بروزرسانی در هنگام تغییر سورس کد و حوزه کاربرد کوچک ( تشخیص خطاهای عملکردی ) می باشد.
تحلیل گر کد ایستا چیست ؟
تحلیل گر کد ایستا ( Static Analyzer ) مشابه کامپایلر درستی کد را بررسی می کند ولی گزارش کامل تری نسبت به کامپایلر در مورد کد نوشته شده به ما می دهد. این گزارش شامل یک سری Error ها، Warning ها، Style Issue ها و … میتواند باشد که شامل مشکلاتی است که مربوط به رعایت نکردن اصول کدنویسی امن می باشد. آنها آسیبپذیریهایی را در کد گزارش میکنند که میتواند منجر به مشکلات احتمالی شود. تحلیل گر کد ایستا میتواند طبق اصول و استانداردهای خود کد را جستجوی عمیق کرده و بنابراین پروسه اجرایی آن ها از کامپایل کردن کمی آهسته تر است. مزایای استفاده از تحلیل گر کد ایستا کاهش نرخ خطا ( error-rate )، افزایش قابلیت اطمینان ( reliability ) افزایش ایمنی ( Safety )، افزایش امنیت ( Security ) و نیز برآورده شدن استانداردهای کدنویسی ایمن می باشد.
توجه داشته باشید که تمام تحلیل های انجام شده توسط تحلیل گرهای کد ایستا توافقی است؛ در واقع این ابزارها false-positive هستند و بسیاری از پیغام های خطایی که می دهند نادرست است. ابزارهای تحلیل گر کد ایستا علاوه بر تولید یک سری پیغام های خطای نادرست لزوما نمی توانند تمام عیوب کد را نیز تشخیص دهند. یعنی بعد از استفاده از این ابزارها نمیتوانید از عدم وجود اشکال در کد خود مطمئن باشید. سوالی که اینجا پیش می آید این است که تجزیه و تحلیل ایستای کد وقتی همیشه نمی تواند صحیح باشد، چرا کنار گذاشته نمی شود؟
معرفی انواع تحلیل گرهای کد
ابزارهای تحلیل گر کد میتوانند به حلقه Build در IDE اضافه شوند یا میتوان از آن ها به صورت کامندلاین ( Command line ) استفاده کرد. برخی از آن ها دارای GUI هستند و برخی دیگر از طریق افزودن به صورت پلاگین روی برخی IDE ها استفاده می شوند. برخی از نرم افزارهای IDE نظیر Visual Studio و Eclipse دارای ابزارهای داخلی تحلیل گر کد هستند و برای آنالیز بیشتر قابلیت نصب پلاگین را دارند. ابزارهای تحلیل گر کد در لایسنس های تجاری یا متن باز ( رایگان ) در دسترس هستند. cppcheck و IKOS دو نمونه از ابزارهای تحلیل گر کد متن باز معروف هستند. همچنین Coverity و PC-lint نام های ابزارهای تحلیل گر کد معروف با لایسنس تجاری هستند که به ترتیب برای شرکت های Synopsys و Gimpel می باشند. از دیگر ابزارهای تحلیل گر کد معروف میتوان LDRA ، Parasoft ، PVS Studio و VectorCast را نام برد.
cppcheck چیست ؟
یک ابزار تحلیل گر کد ایستا ( Static Analyzer ) متن باز و رایگان می باشد که بوسیله کامندلاین ( command line ) اجرا می شود و برای پلتفورم های مختلف عرضه شده است. این ابزار می تواند خطاهای کدنویسی را به صورت اتوماتیک در سه بخش Error، Warning و Style Issue جستجو کرده و گزارش دهد. مواردی نظیر نوشتن در خارج از یک آرایه ( array overrun )، نشت حافظه و منابع ( memory and resource leaks )، متغیرهای بدون استفاده و …
نصب و راه اندازی cppcheck در ویندوز
برای نصب این ابزار کافی است ابتدا آخرین نسخه را در بخش release صفحه گیت هاب cppcheck انتخاب کنید سپس فایل نصبی مناسب را دانلود و نصب کنید. در زمان نوشتن این مقاله آخرین نسخه منتشر شده 2.9 می باشد.
بعد از نصب شدن cppcheck بایستی به System variable ویندوز آن را معرفی کرد. برای این کار ابتدا به control panel و بخش systems بروید سپس در بخش سمت راست روی Advanced system settings کلیک کنید. در صفحه باز شده روی Environment Variables کلیک کنید.
در صفحه متغیرهای سیستم در قسمت پایین بایستی همانند شکل زیر محل نصب نرم افزار cppcheck را به path اضافه کنید.
اگر مراحل را درست انجام داده باشید با وارد کردن کلمه cppcheck در یکی از ابزارهای کامند لاین در دسترس ( مثل PoweShell یا Git Bash ) راهنمای استفاده از cppcheck نمایش داده می شود.
افزودن cppcheck در نرم افزار keil
از ابزار cppcheck میتوانید هم بیرون از نرم افزار keil ( در ابزارهای PoweShell ویندوز یا Git Bash ) و هم درون برنامه keil به صورت زیر استفاده کنید. برای افزودن این ابزار درون نرم افزار keil از منوی Tools به بخش Customize Tools Menu بروید و با زدن گزینه New مشابه شکل زیر cppcheck را به نرم افزار keil معرفی کنید.
در بخش Command بایستی مسیر نصب شده فایل cppcheck.exe را وارد کنید و در بخش Arguments هم مطابق شکل mkdir $P را وارد کنید که همواره مسیر کنونی پروژه Keil را به cppcheck معرفی می کند. حالا اگر بخواهیم برای مثال یک فایل ساده را توسط cppcheck بررسی نماییم کافی است از منوی Tools گزینه cppcheck را انتخاب کنیم تا دستوری که در مرحله قبل نوشتیم اجرا شود. شکل زیر پیغام خطای متناسب با برنامه اشتباه نوشته شده ما را نشان می دهد.
همانطور که مشاهده می کنید خطای موجود در کد از نوع Array Index Out Of Bounds می باشد که توسط کامپایلر خود Keil به صورت Warning شناسایی شده است اما به درستی کامپایل شده و قابلیت پروگرام شدن و اجرا شدن را دارد. اما چنین خطایی در cppcheck به صورت Error نمایش داده شده است که نشان می دهد این خطا بسیار مهلک است.
دیدگاهتان را بنویسید