| FLAWFINDER(1) | Flawfinder | FLAWFINDER(1) |
نام (NAME)
flawfinder - یافتن واژگانی رخنهها و نقصهای امنیتی بالقوه («یافتهها») در کد منبع
خلاصه دستور (SYNOPSIS)
flawfinder [--help|-h] [--version]
[--listrules]
[--allowlink] [--followdotdir] [--nolink]
[--patch=filename|-P filename]
[--inputs|-I] [ --minlevel=X |
-m X ] [--falsepositive|-F]
[--neverignore|-n]
[--regex=PATTERN | -e PATTERN]
[--context|-c] [--columns|-C] [--csv]
[--dataonly|-D] [--html|-H]
[--immediate|-i] [--sarif]
[--singleline|-S] [--omittime]
[--quiet|-Q] [--error-level=LEVEL]
[--loadhitlist=F] [--savehitlist=F]
[--diffhitlist=F]
[--] [ فایل کد
منبع یا
دایرکتوری
ریشهٔ منبع
]+
توضیحات (DESCRIPTION)
دستور flawfinder در کدهای منبع C/C++ به دنبال رخنهها و نقصهای امنیتی بالقوه جستجو میکند. برای اجرای flawfinder، کافی است فهرستی از دایرکتوریها یا فایلها را به آن بدهید. به ازای هر دایرکتوری مشخصشده، تمام فایلهایی که دارای پسوند نام فایل C/C++ در آن دایرکتوری (و زیردایرکتوریهای آن، به صورت بازگشتی) هستند، بررسی خواهند شد. بنابراین، برای بیشتر پروژهها کافی است نام بالاترین دایرکتوری کد منبع را به flawfinder بدهید (از «.» برای دایرکتوری جاری استفاده کنید)، و flawfinder تمام کدهای منبع C/C++ پروژه را بررسی خواهد کرد. دستور flawfinder نیازی به این ندارد که شما حتماً قادر به ساخت (build) نرمافزار خود باشید؛ بنابراین حتی برای کدهای منبع ناقص نیز قابل استفاده است. اگر فقط میخواهید تغییرات بررسی شوند، یک unified diff از آن تغییرات (ایجاد شده با "diff -u" مربوط به GNU یا "svn diff" یا "git diff") را در یک فایل وصله (patch) ذخیره کرده و از گزینهٔ --patch (-P) استفاده کنید.
دستور flawfinder فهرستی از «یافتهها» (hits یا همان نقایص امنیتی بالقوه که یافته یا findings نیز نامیده میشوند) تولید میکند که بر اساس میزان ریسک مرتب شدهاند؛ مواردی که بیشترین ریسک را دارند ابتدا نمایش داده میشوند. سطح ریسک در داخل براکتها نمایش داده میشود و از ۰ (ریسک بسیار کم) تا ۵ (ریسک بسیار زیاد) متغیر است. این سطح ریسک نه تنها به تابع، بلکه به مقادیر پارامترهای تابع نیز بستگی دارد. برای مثال، رشتههای ثابت اغلب در بسیاری از زمینهها کمخطرتر از رشتههای کاملاً متغیر هستند، و در چنین شرایطی یافته سطح ریسک پایینتری خواهد داشت. ابزار flawfinder کتابخانهٔ gettext (کتابخانهای رایج برای برنامههای بینالمللیسازیشده) را میشناسد و با رشتههای ثابتی که از طریق gettext ارسال میشوند مانند رشتههای ثابت رفتار میکند؛ این کار تعداد یافتههای کاذب را در برنامههای بینالمللیسازیشده کاهش میدهد. دستور flawfinder با _T() و _TEXT()، ماکروهای رایج مایکروسافت برای مدیریت برنامههای بینالمللیسازیشده، نیز رفتاری مشابه دارد. ابزار flawfinder متنهای داخل کامنتها و رشتهها را به درستی نادیده میگیرد. به طور معمول، flawfinder تمام یافتهها با سطح ریسک حداقل ۱ را نشان میدهد، اما اگر مایل باشید میتوانید از گزینهٔ --minlevel برای نمایش یافتههایی با سطوح ریسک بالاتر استفاده کنید. توضیحات یافتهها همچنین شناسه(های) مربوط به شمارش ضعفهای رایج (CWE یا Common Weakness Enumeration) را همانطور که در ادامه توضیح داده شده، داخل پرانتز ذکر میکند. ابزار flawfinder رسماً با CWE سازگار است (CWE-Compatible). توضیحات یافتههای حاوی "[MS-banned]" نشاندهندهٔ توابعی هستند که در فهرست توابع ممنوعهٔ ارائهشده توسط مایکروسافت قرار دارند؛ برای اطلاعات بیشتر دربارهٔ توابع ممنوعه به http://msdn.microsoft.com/en-us/library/bb288454.aspx مراجعه کنید.
هر یافتهای لزوماً یک آسیبپذیری امنیتی واقعی نیست و هر آسیبپذیری امنیتی نیز الزاماً پیدا نمیشود. با این وجود، flawfinder میتواند ابزاری کمکی در یافتن و رفع آسیبپذیریهای امنیتی باشد. یک روش متداول برای استفاده از flawfinder این است که ابتدا آن را روی مجموعهای از کدهای منبع اجرا کرده و موارد با بیشترین ریسک را بررسی کنید. سپس از --inputs برای بررسی مکانهای ورودی استفاده کنید و مطمئن شوید که تنها مقادیر ورودی مجاز و امن از کاربران غیرقابلاعتماد دریافت میشوند.
پس از بازبینی یک برنامه، میتوانید خطوطی از کد منبع را که در واقع مشکلی ندارند اما هشدارهای کاذب ایجاد میکنند علامتگذاری کنید تا flawfinder دیگر دربارهٔ آنها هشدار ندهد. برای علامتگذاری یک خط جهت نادیده گرفتن این هشدارها، یک کامنت با قالببندی ویژه در همان خط (پس از کد منبع) یا به تنهایی در خط قبلی قرار دهید. این کامنت باید یکی از دو قالب زیر را داشته باشد:
- // Flawfinder: ignore
- /* Flawfinder: ignore */
جهت سازگاری، میتوانید "Flawfinder:" را در این کامنتهای ویژه با "ITS4:" یا "RATS:" جایگزین کنید. از آنجا که ممکن است این خطوط اشتباه باشند، میتوانید از گزینهٔ --neverignore استفاده کنید که باعث میشود flawfinder بدون توجه به دستورات کامنت، هرگز هیچ خطی را نادیده نگیرد (به بیانی دیگر، --neverignore موارد نادیدهگرفتهشده را نادیده میگیرد!).
ابزار flawfinder از یک پایگاهدادهٔ داخلی به نام «مجموعه قوانین» (ruleset) استفاده میکند؛ این مجموعه قوانین توابعی را شناسایی میکند که علل رایج نقصهای امنیتی هستند. مجموعه قوانین استاندارد شامل شمار زیادی از مشکلات بالقوهٔ مختلف است، از جمله مشکلات عمومی که میتوانند بر هر برنامهٔ C/C++ تأثیر بگذارند، و همچنین تعدادی از توابع خاص سیستمعاملهای شبهیونیکس و ویندوز که بهویژه مشکلساز هستند. گزینهٔ --listrules فهرست قوانین فعلی و سطح ریسک پیشفرض آنها را گزارش میکند. همانطور که در بالا اشاره شد، هر نقص امنیتی بالقوه که در یک فایل کد منبع مشخص پیدا شود (و با مدخلی در مجموعه قوانین مطابقت داشته باشد) یک «یافته» (hit) نامیده میشود، و مجموعهٔ یافتههای پیدا شده در طول هر بار اجرای برنامه، «فهرست یافتهها» (hitlist) نام دارد. فهرست یافتهها را میتوان ذخیره کرد (با استفاده از --savehitlist)، دوباره برای نمایش مجدد بارگذاری کرد (با استفاده از --loadhitlist)، و همچنین میتوان تنها یافتههایی را که با اجرای دیگر تفاوت دارند نمایش داد (با استفاده از --diffhitlist).
ابزار flawfinder یک ابزار ساده است که این سادگی مزایا و معایب اساسی خاص خود را به همراه دارد. عملکرد flawfinder بر اساس توکنبندی واژگانی ساده (نادیده گرفتن کامنتها و توکنبندی صحیح رشتهها) و جستجو برای تطابق توکنها با پایگاهداده (بهویژه برای یافتن فراخوانی توابع) است. از این رو flawfinder مشابه RATS و ITS4 است که آنها نیز از توکنبندی واژگانی ساده استفاده میکنند. سپس flawfinder متن پارامترهای تابع را برای تخمین ریسک بررسی میکند. برخلاف ابزارهایی مانند splint، پرچمهای هشدار gcc، و clang، ابزار flawfinder هنگام جستجوی آسیبپذیریهای بالقوه یا تخمین سطح ریسک، از اطلاعات مربوط به جریان کنترل (control flow)، جریان داده (data flow) یا انواع داده (data types) استفاده نمیکند و به آنها دسترسی ندارد. بنابراین، flawfinder ناگزیر مثبتهای کاذب (false positive) فراوانی برای آسیبپذیریها تولید میکند و از گزارش بسیاری از آسیبپذیریها نیز باز میماند. از طرف دیگر، flawfinder میتواند آسیبپذیریها را در برنامههایی که نمیتوان آنها را ساخت یا پیوند (link) داد، پیدا کند. این ابزار اغلب میتواند با برنامههایی که حتی قابل کامپایل نیستند (حداقل توسط ابزارهای بازبین) کار کند. همچنین flawfinder چندان توسط تعاریف ماکروها و سایر موارد نامتعارفی که ابزارهای پیچیدهتر با آنها به مشکل میخورند، سردرگم نمیشود. علاوه بر این، flawfinder میتواند به عنوان یک مقدمهٔ ساده برای ابزارهای تحلیل ایستای کد به طور کلی مفید باشد، زیرا شروع کار با آن و درکش بسیار آسان است.
محدودیتهای flawfinder بر هر تحلیلی تأثیر میگذارد، اما هنگام تحلیل C++ میتواند بهویژه محدودکنندهتر باشد. زبان C++ به تجزیهٔ (parse) دشوار و پیچیده شهرت دارد. یک سامانهٔ واژگانی مانند flawfinder در مواجهه با سازههایی چون فضاهای نام (namespaces) و حوزههای کلاس (class scopes) با محدودیت مواجه است. دستور flawfinder از روشهای ابتکاری (heuristics) متعددی برای بهبود کارایی خود استفاده میکند. با این حال، flawfinder در برنامههای C++ که «عمدتاً C با چند افزودهٔ C++» هستند کارآمدتر است و در برنامههای C++ که از «C++ مدرن کامل» با استفادهٔ قابلتوجه از این ویژگیها بهره میبرند، کارایی کمتری دارد.
میتوان از flawfinder در کنار ابزارهای تحلیل کد مبتنی بر هوش مصنوعی استفاده کرد. خروجی flawfinder میتواند برای شناسایی سریع بخشهایی از کد که نیازمند توجه دقیقتر هستند به کار رود تا سپس یک سامانهٔ هوش مصنوعی بتواند آنها را با جزئیات بیشتر بررسی کند.
هر نام فایلی که در خط فرمان مشخص شود (حتی اگر پسوند معمول فایلهای C/C++ را نداشته باشد) بررسی خواهد شد؛ بنابراین میتوانید flawfinder را وادار کنید هر فایل خاصی را که میخواهید بررسی کند. هنگام جستجوی بازگشتی در دایرکتوریها، flawfinder تنها فایلهای عادی را که دارای پسوندهای C/C++ هستند باز و بررسی میکند. دستور flawfinder فایلهایی را که دارای پسوندهای ".c"، ".h"، ".ec"، ".ecp"، ".pgc"، ".C"، ".cpp"، ".CPP"، ".cxx"، ".c++"، ".cc"، ".CC"، ".pcc"، ".hpp" یا ".H" باشند، فایل C/C++ در نظر میگیرد. نام فایل «-» به معنای ورودی استاندارد (standard input) است. برای جلوگیری از مشکلات امنیتی، فایلهای ویژه (مانند فایلهای ویژه دستگاه و لولههای نامگذاریشده یا named pipes) همیشه نادیده گرفته میشوند و به طور پیشفرض پیوندهای نمادین (symbolic links) نیز نادیده گرفته میشوند (گزینهٔ --allowlink پیوندهای نمادین را دنبال میکند)..PP پس از فهرست یافتهها (hits)، خلاصهای کوتاه از نتایج قرار دارد (از -D برای حذف این اطلاعات استفاده کنید). این بخش تعداد یافتهها، خطوط تحلیلشده (همانطور که توسط wc -l گزارش میشود)، و خطوط فیزیکی کد مبدأ (SLOC) تحلیلشده را نشان میدهد. یک SLOC فیزیکی، خطی غیرخالی و بدون توضیح (کامنت) است. سپس تعداد یافتهها در هر سطح نشان داده میشود؛ توجه داشته باشید که هرگز یافتهای در سطحی پایینتر از minlevel (بهطور پیشفرض ۱) وجود نخواهد داشت. بنابراین، «[0] 0 [1] 9» بدان معناست که در سطح ۰ هیچ یافتهای گزارش نشده، و در سطح ۱ تعداد ۹ یافته گزارش شده است. در ادامه، تعداد یافتهها در یک سطح مشخص یا بالاتر نشان داده میشود (بنابراین سطح 3+ شامل مجموع تعداد یافتهها در سطوح ۳، ۴ و ۵ است). بدین ترتیب، ورودی «[0+] 37» نشان میدهد که در سطح ۰ یا بالاتر ۳۷ یافته وجود داشته است (ورودی 0+ همیشه با تعداد کل «یافتهها» در بالا یکسان خواهد بود). سپس یافتهها به ازای KSLOC نشان داده میشود؛ این مقدار برابر است با هر یک از مقادیر «سطح یا بالاتر» ضرب در ۱۰۰۰ و تقسیم بر SLOC فیزیکی. اگر پیوندهای نمادین (symlinks) نادیده گرفته شده باشند، تعداد آنها گزارش میشود. اگر یافتهها نادیده گرفته شده باشند (با استفاده از دستورالعمل «ignore» در توضیحات کد مبدأ، همانطور که در بالا شرح داده شد)، تعداد موارد نادیدهگرفتهشده گزارش میشود. حداقل سطح خطر برای گنجانده شدن در گزارش نمایش داده میشود؛ این مقدار بهطور پیشفرض ۱ است (از --minlevel برای تغییر آن استفاده کنید). این خلاصه با یادآوریهای مهمی به پایان میرسد: هر یافتهای لزوماً یک آسیبپذیری امنیتی نیست، و ممکن است آسیبپذیریهای امنیتی دیگری نیز وجود داشته باشند که توسط این ابزار گزارش نشدهاند.
ابزار Flawfinder میتواند بهسادگی در سامانههای یکپارچهسازی مداوم (continuous integration) ادغام شود. شاید مایل باشید برای کمک به این کار، گزینه --error-level را بررسی کنید؛ برای نمونه، استفاده از --error-level=4 باعث میشود که در صورت یافتن آسیبپذیری در سطح ۴ یا بالاتر توسط flawfinder، یک خطا برگردانده شود.
ابزار Flawfinder تحت مجوز GNU GPL نسخه ۲ یا بالاتر (GPLv2+) منتشر شده است.
ابزار Flawfinder عملکردی مشابه با برنامه دیگری به نام ITS4 دارد، که نه یک نرمافزار کاملاً متنباز (طبق تعریف Open Source Definition) و نه نرمافزار آزاد (طبق تعریف Free Software Foundation) است. نویسنده Flawfinder هرگز کد مبدأ ITS4 را ندیده است. همچنین اگر با RATS آشنایی دارید، Flawfinder از جهات متعددی به RATS شباهت دارد.
آموزش کوتاه (BRIEF TUTORIAL)
در اینجا مثالی کوتاه از نحوه استفاده از flawfinder آورده شده است. تصور کنید که کد مبدأ C/C++ برنامهای به نام xyzzy را در اختیار دارید (که ممکن است خودتان آن را نوشته باشید یا خیر)، و در حال جستجوی آسیبپذیریهای امنیتی هستید (تا بتوانید پیش از آنکه مشتریان با این آسیبپذیریها مواجه شوند، آنها را برطرف کنید). برای این آموزش، فرض میشود که از یک سیستم شبهیونیکس (Unix-like) مانند Linux، OpenBSD یا MacOS X استفاده میکنید.
اگر کد مبدأ در زیرپوشهای به نام xyzzy قرار دارد، احتمالاً با باز کردن یک پنجره متنی و استفاده از تنظیمات پیشفرض flawfinder شروع خواهید کرد تا برنامه تحلیل شده و فهرستی اولویتبندیشده از آسیبپذیریهای امنیتی بالقوه گزارش شود (دستور «less» صرفاً برای اطمینان از این است که نتایج روی صفحه باقی بمانند):
در این مرحله، شمار زیادی از مدخلها را مشاهده خواهید کرد. هر مدخل دارای نام فایل، یک دونقطه، شماره خط، یک سطح خطر در قلابها (که ۵ پرخطرترین است)، یک دستهبندی، نام تابع، و توضیحی درباره دلیل اینکه چرا flawfinder آن خط را یک آسیبپذیری میداند، است. ابزار Flawfinder معمولاً بر اساس سطح خطر مرتبسازی میکند و پرخطرترین موارد را در ابتدا نشان میدهد؛ اگر زمان محدودی دارید، احتمالاً بهتر است کار را روی پرخطرترین موارد آغاز کرده و تا زمان اتمام وقت ادامه دهید. اگر میخواهید نمایش را تنها به خطراتی با یک سطح خطر مشخص یا بالاتر محدود کنید، از گزینه --minlevel استفاده کنید. اگر بهدلیل شباهت نام متغیرها به نام توابع خطرناک، با تعداد فوقالعاده زیادی از موارد مثبت کاذب (false positives) مواجه شدید، از گزینه -F برای حذف گزارشهای مربوط به آنها استفاده کنید. اگر پیام خطا را متوجه نمیشوید، لطفاً اسنادی مانند Secure Programming HOWTO در https://dwheeler.com/secure-programs را مشاهده کنید که اطلاعات بیشتری در رابطه با نوشتن برنامههای امن ارائه میدهد.
هنگامی که مشکل را شناسایی کرده و آن را درک کردید، میتوانید آن را برطرف کنید. گاهی ممکن است بخواهید تحلیل را دوباره انجام دهید؛ هم به این دلیل که شماره خطوط تغییر خواهند کرد و هم برای اطمینان از اینکه کد جدید آسیبپذیری متفاوت دیگری ایجاد نکرده باشد.
اگر تشخیص دادهاید که خطی واقعاً مشکلی ندارد و از آن مطمئن هستید، میتوانید درست قبل از خط مربوطه یا بر روی همان خط، توضیحی مانند
/* Flawfinder: ignore */
پس از انجام آن، باید برگردید و ورودیهای برنامه را جستجو کنید تا اطمینان حاصل شود که برنامه تمامی ورودیهای غیرقابلاعتماد خود را بهطور دقیق پالایش میکند. ابزار Flawfinder میتواند بسیاری از ورودیهای برنامه را با استفاده از گزینه --inputs شناسایی کند، مانند این:
ابزار Flawfinder میتواند بهخوبی با ویرایشگرهای متن و محیطهای یکپارچه توسعه نرمافزار (IDE) ادغام شود؛ برای اطلاعات بیشتر، به بخش مثالها مراجعه کنید.
ابزار Flawfinder شامل گزینههای متعدد دیگری نیز هست، از جمله گزینههایی برای ایجاد نسخههای HTML از خروجی (مفید برای نمایش زیباتر) و خروجی در قالب OASIS Static Analysis Results Interchange Format (SARIF). بخش بعدی این گزینهها را با جزئیات بیشتر شرح میدهد.
گزینهها (OPTIONS)
ابزار Flawfinder دارای چندین گزینه است که میتوان آنها را در دستههای زیر گروهبندی کرد: گزینههایی که مستندات خود برنامه را کنترل میکنند، دادههای ورودی را انتخاب میکنند، مشخص میکنند کدام یافتهها نمایش داده شوند، قالب خروجی را تعیین میکنند، و مدیریت فهرست یافتهها را انجام میدهند. گزینههای پرکاربرد flawfinder از نحو استاندارد گزینهها تعریفشده در بخش «Utility Conventions» استاندارد POSIX (ویرایش ۷، نسخه ۲۰۱۳) پشتیبانی میکنند. ابزار Flawfinder همچنین از گزینههای بلند GNU (گزینههای دو خط تیره به شکل --option) همانطور که در «Program Argument Syntax Conventions» در GNU C Library Reference Manual و «Standards for Command Line Interfaces» در GNU Coding Standards تعریف شده است، پشتیبانی میکند. آرگومانهای گزینههای بلند را میتوان به صورت «--name=value» یا «-name value» ارائه داد. تمام گزینهها با استفاده از قراردادهای خواناتر گزینههای بلند GNU قابل دسترسی هستند؛ برخی از گزینههای کمکاربردتر تنها با استفاده از قراردادهای گزینههای بلند قابل دسترسی میباشند..SS "مستندات (Documentation)"
- --help
- -h
- نمایش اطلاعات نحوه استفاده (راهنما).
- --version
- (تنها) شماره نسخه را نمایش داده و خارج میشود.
- --listrules
- فهرست کردن اصطلاحات (نشانهها یا tokens) که بررسیهای بیشتر را آغاز میکنند، سطح خطر پیشفرض آنها و هشدار پیشفرض (شامل شناسه(های) CWE، در صورت وجود)، همگی جدا شده با کلید Tab. این اصطلاحات در درجهٔ اول نام توابع بالقوه خطرناک هستند. توجه داشته باشید که سطح خطر و هشدار گزارششده برای برخی از کدهای خاص ممکن است بسته به نحوهٔ استفاده از اصطلاح، با مقدار پیشفرض متفاوت باشد. اگر سربرگ معمول را نمیخواهید، آن را با -D ترکیب کنید. در نسخهٔ 1.29 نرمافزار flawfinder جداکننده از فاصله به Tab تغییر یافت و فیلد هشدار پیشفرض اضافه شد.
انتخاب دادههای ورودی (Selecting Input Data)
- --allowlink
- اجازه دادن به استفاده از پیوندهای نمادین؛ بهطور معمول از پیوندهای نمادین صرفنظر میشود. اگر در حال تحلیل کد دیگران هستید از این گزینه استفاده نکنید؛ مهاجمان میتوانند کارهای متعددی انجام دهند تا در فرایند تحلیلی که این گزینه در آن فعال است مشکل ایجاد کنند. برای مثال، یک مهاجم میتواند پیوندهای نمادینی به فایلهایی مانند /etc/passwd ایجاد کند (که موجب افشای اطلاعات مربوط به فایل میشود) یا یک حلقهٔ تکرار نامحدود ایجاد کند که باعث میشود flawfinder «تا ابد» اجرا شود. مشکل دیگرِ فعالسازی این گزینه این است که اگر به یک فایل یکسان با استفاده از پیوندهای نمادین چندین بار ارجاع داده شود، چند بار تحلیل خواهد شد (و در نتیجه چند بار گزارش میشود). توجه داشته باشید که flawfinder از قبل شامل تمهیدات حفاظتی در برابر پیوندهای نمادین به انواع فایلهای خاص مانند فایلهای دستگاه (به عنوان مثال /dev/zero یا C:\mystuff\com1) است. توجه داشته باشید که در نسخهٔ 1.01 و قبلتر flawfinder، این رفتار پیشفرض بود.
- --followdotdir
- ورود به دایرکتوریهایی که نام آنها با "." آغاز میشود. بهطور معمول این دایرکتوریها نادیده گرفته میشوند، زیرا معمولاً شامل دادههای خصوصی سیستمهای کنترل نسخه (مانند .git/ یا .svn/)، فرادهادههای ساخت (مانند .makepp)، اطلاعات پیکربندی و مواردی از این دست هستند.
- --nolink
- نادیده گرفته میشود. از نظر تاریخی، این گزینه دنبال کردن پیوندهای نمادین را غیرفعال میکرد؛ این رفتار اکنون پیشفرض است.
- --patch=patchfile
- -P patchfile
- بررسی فایلها یا دایرکتوریهای انتخابشده، اما فقط گزارش نتایج در خطوطی که طبق شرح ارائهشده در فایل وصله (patch) اضافه یا تغییر یافتهاند. فایل وصله باید در یک قالب شناختهشدهٔ unified diff باشد (برای مثال، خروجی GNU "diff -u old new"، "svn diff" یا "git diff [commit]"). نرمافزار Flawfinder فرض میکند که وصله از قبل بر روی فایلها اعمال شده است. فایل وصله همچنین میتواند شامل تغییراتی در فایلهای نامربوط باشد (آنها صرفاً نادیده گرفته خواهند شد). شماره خطوط ارائهشده در فایل وصله برای تعیین اینکه چه خطوطی تغییر کردهاند استفاده میشوند، بنابراین اگر پس از ایجاد فایل وصله، فایلها را تغییر دادهاید، ابتدا فایل وصله را دوباره ایجاد کنید. توجه داشته باشید که نام فایلهای جدید ارائهشده در فایل وصله باید دقیقاً مطابقت داشته باشد، از جمله حروف بزرگ/کوچک، پیشوند مسیر، و جداکننده دایرکتوری (\ در مقابل /). تنها قالب unified diff پذیرفته میشود (خروجی GNU diff، svn diff، و git diff مشکلی ندارد)؛ اگر قالب متفاوتی دارید، مجدداً ابتدا آن را بازتولید کنید. تنها مواردی گزارش میشوند که در خطوط تغییریافته حاصل، یا بلافاصله در بالا و پایین آنها رخ داده باشند. این گزینه متضمن --neverignore است. هشدار: فایل وصله را بدون -P ارسال نکنید، زیرا در این صورت flawfinder سعی میکند با آن فایل مانند یک فایل منبع رفتار کند. این کار اغلب ممکن است نتیجه دهد، اما شماره خطوط نسبت به ابتدای فایل وصله خواهد بود، نه موقعیتها در کد منبع. توجه داشته باشید که شما باید فایلهای واقعی را نیز برای تحلیل ارائه دهید، نه فقط فایل وصله را؛ هنگام استفاده از -P فایلها تنها در صورتی گزارش میشوند که هم در وصله فهرست شده باشند و هم (مستقیم یا غیرمستقیم) در فهرست فایلهای مورد تحلیل قرار داشته باشند.
انتخاب موارد شناساییشده برای نمایش (Selecting Hits to Display)
- --inputs
- -I
- تنها توابعی را نمایش میدهد که دادهها را از خارج برنامه دریافت میکنند؛ این گزینه همچنین minlevel را روی 0 تنظیم میکند.
- --minlevel=X
- -m X
- تنظیم حداقل سطح خطر روی X برای قرارگیری در فهرست موارد شناساییشده (hitlist). این مقدار میتواند از 0 (``بدون خطر'') تا 5 (``بیشترین خطر'') باشد؛ پیشفرض 1 است.
- --falsepositive
- -F
- مواردی را که احتمالاً مثبت کاذب هستند، در خروجی قرار ندهد. در حال حاضر، این بدان معناست که نامهای توابع اگر به دنبال آنها "(" نیامده باشد نادیده گرفته میشوند، و تعریف آرایههای نویسهای ثبت نمیشوند. بنابراین، اگر در همهجا از متغیری به نام "access" استفاده کنید، این کار ارجاعات به این متغیر معمولی را حذف خواهد کرد. این گزینه پیشفرض نیست، زیرا احتمال نادیده گرفتن موارد شناساییشدهٔ مهم را نیز افزایش میدهد؛ بهویژه، نام توابع در عبارتهای #define و فراخوانیها از طریق اشارهگرهای تابع از دست خواهند رفت.
- --neverignore
- -n
- هرگز مشکلات امنیتی نادیده گرفته نشوند، حتی اگر یک دستورالعمل ``ignore'' در کامنت داشته باشند.
- --regexp=PATTERN
- -e PATTERN
- تنها مواردی گزارش شوند که متنی منطبق با الگوی عبارت باقاعدهٔ PATTERN داشته باشند. برای مثال، جهت گزارش تنها مواردی که شامل متن "CWE-120" هستند، از ``--regex CWE-120'' استفاده کنید. نام این پرچمهای گزینه مشابه grep است..SS "انتخاب قالب خروجی (Selecting Output Format)"
- --columns
- -C
- نمایش شماره ستون (همراه با نام فایل و شماره خط) برای هر مورد یافتهشده؛ این مقدار پس از شماره خط با افزودن یک دونقطه و سپس شماره ستون در خط نشان داده میشود (نخستین نویسه در یک خط، ستون شماره ۱ است). این قابلیت برای ویرایشگرهایی که میتوانند به ستونهای خاصی پرش کنند، یا برای یکپارچهسازی با سایر ابزارها (مانند ابزارهایی برای فیلتر کردن بیشتر موارد مثبت کاذب) مفید است.
- --context
- -c
- نمایش زمینه (context)، یعنی خطی که دارای «مورد یافتهشده»/نقص احتمالی است. بهطور پیشفرض، این خط بلافاصله پس از هشدار نمایش داده میشود.
- --csv
- تولید خروجی در قالب مقادیر جداشده با کاما (CSV). این قالب برای ارسال به سایر ابزارها جهت پردازش توصیه میشود. این گزینه همواره یک سطر سرایند و در پی آن ۰ یا چند سطر داده تولید میکند (یک سطر داده برای هر مورد یافتهشده). انتخاب این گزینه بهطور خودکار --quiet و --dataonly را فعال میکند. بیشتر سرایندها خودتوضیح هستند: "File" نام فایل است، "Line" شماره خط، "Column" ستون (شروع از ۱)، "Level" سطح خطر (۰ تا ۵، ۵ پرخطرترین است)، "Category" دستهبندی عمومی flawfinder، "Name" نام قاعدهای که فعال شده است، "Warning" متنی که علت ثبت این یافته را توضیح میدهد، "Suggestion" متنی شامل پیشنهاد برای رفع آن، "Note" سایر یادداشتهای توضیحی، "CWEs" فهرست یک یا چند شناسه CWE، "Context" خط کد منبعی که موجب ثبت این مورد شده است، و "Fingerprint" هش SHA-256 از زمینه است، پس از آنکه فاصلههای خالی ابتدا و انتهای آن حذف شده باشد (این اثرانگشت ممکن است به شناسایی و حذف موارد تکراری در آینده کمک کند). اگر از Python3 استفاده میکنید، هش از زمینهای که با UTF-8 کدگذاری شده محاسبه میشود.
- --dataonly
- -D
- عدم نمایش سرایند (header) و پاورقی (footer). از این گزینه همراه با --quiet استفاده کنید تا فقط خود دادهها را مشاهده نمایید.
- --html
- -H
- قالببندی خروجی بهصورت HTML به جای متن ساده.
- --immediate
- -i
- نمایش فوری موارد یافتهشده (منتظر نماندن تا پایان تحلیل).
- --sarif
- تولید
خروجی در
قالب OASIS Static Analysis Results Interchange
Format (SARIF) (یک قالب
بر پایه JSON).
اهداف قالب
SARIF،
همانطور
که در نگارش
2.1.0 (۲۷ مارس
۲۰۲۰) از
مشخصات فنی
آن آمده
است، شامل
توانایی
«ثبت جامع
گستره
دادههای
تولیدشده
توسط
ابزارهای
پرکاربرد
تحلیل
ایستا»
میباشد.
خروجی SARIF نام
ابزار را
"Flawfinder" قید
میکند.
سطوح ۰ تا ۵
در flawfinder به
رتبه (rank) در SARIF
(با تقسیم
بر ۵)، سطح (level)
در SARIF، و
اقدام
پیشفرض
نمایشگر
بهصورت
زیر نگاشت
میشوند:
Flawfinder 0: SARIF rank 0.0, SARIF level note, بهطور پیشفرض نمایش داده نمیشود
Flawfinder 1: SARIF rank 0.2, SARIF level note, بهطور پیشفرض نمایش داده نمیشود
Flawfinder 2: SARIF rank 0.4, SARIF level note, بهطور پیشفرض نمایش داده نمیشود
Flawfinder 3: SARIF rank 0.6, SARIF level warning, بهطور پیشفرض نمایش داده میشود، فرایند ساخت / سایر فرایندها را متوقف نمیکند
Flawfinder 4: SARIF rank 0.8, SARIF level error, بهطور پیشفرض نمایش داده میشود، فرایند ساخت / سایر فرایندها را متوقف میکند
Flawfinder 5: SARIF rank 1.0, SARIF level error, بهطور پیشفرض نمایش داده میشود، فرایند ساخت / سایر فرایندها را متوقف میکند
با تشکر فراوان از Yong Yan برای پیادهسازی تولید خروجی SARIF در flawfinder! برای اطلاعات بیشتر درباره قالب SARIF، ببینید: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif
- --singleline
- -S
- نمایش خروجی بهصورت یک خط متنی برای هر مورد یافتهشده. برای تعامل با ابزارهای کامپایل بسیار مفید است.
- --omittime
- حذف اطلاعات زمانبندی. این گزینه برای آزمونهای رگرسیونِ خود flawfinder مفید است، تا خروجی بسته به اینکه تحلیل چقدر طول میکشد تغییر نکند.
- --quiet
- -Q
- عدم نمایش اطلاعات وضعیت (یعنی اینکه چه فایلهایی در حال بررسی هستند) در هنگام انجام تحلیل.
- --error-level=LEVEL
- بازگرداندن یک کد خطای غیرصفر (false) در صورتی که حداقل یک مورد یافتهشده با سطح LEVEL یا بالاتر وجود داشته باشد. اگر یک diffhitlist ارائه شده باشد، موارد ذکرشده در آن نادیده گرفته میشوند. این گزینه میتواند در اسکریپتهای یکپارچهسازی مداوم (CI) مفید باشد، بهویژه اگر خطوط تاییدشده را با "flawfinder: ignore" نشانهگذاری کنید. معمولاً ترجیح بر این است که LEVEL نسبتاً بالا انتخاب شود، مانند ۴ یا ۵. بهطور پیشفرض، flawfinder در اجرای موفقیتآمیز مقدار ۰ (true) را بازمیگرداند..SS "مدیریت فهرست یافتهها (Hitlist Management)"
- --savehitlist=F
- تمام یافتههای حاصل («فهرست یافتهها» یا hitlist) را در F ذخیره میکند.
- --loadhitlist=F
- فهرست یافتهها را به جای تحلیل برنامههای مبدأ، از F بارگذاری میکند. فهرستهای یافتهها برای استفاده توسط همان کاربری که آنها را ایجاد کرده در نظر گرفته شدهاند. یک فهرست یافته از منبعی غیرقابل اعتماد میتواند حاوی نتایج گمراهکننده باشد، مانند یافتههای ساختگی یا یافتههای از قلم افتاده. توجه داشته باشید که فهرستهای یافتههای ذخیرهشده اغلب هنگام استفاده از نسخه قدیمیتر Python قابل خواندن نیستند؛ بهویژه اگر از savehitlist استفاده شده باشد اما flawfinder با Python 3 اجرا شده باشد، این فهرست را نمیتوان با اجرای flawfinder با Python 2 بارگذاری کرد.
- --diffhitlist=F
- تنها یافتههایی (بارگذاریشده یا تحلیلشده) را نشان میدهد که در F نیستند. احتمالاً F قبلاً با استفاده از --savehitlist ایجاد شده است. یک فهرست یافته از منبعی نامعتبر میتواند حاوی نتایج گمراهکننده باشد؛ تنها از فهرستهای یافتهای که خودتان ایجاد کردهاید استفاده کنید. اگر گزینه --loadhitlist داده نشود، این گزینه یافتههای موجود در فایلهای کد مبدأ تحلیلشده را که پیشتر در F ذخیره نشدهاند نمایش میدهد. اگر همراه با --loadhitlist استفاده شود، یافتههای موجود در فهرست یافتههای بارگذاریشده را که در F نیستند نمایش میدهد. الگوریتم مقایسه تفاضلی محافظهکارانه عمل میکند؛ یافتهها تنها در صورتی «یکسان» در نظر گرفته میشوند که نام فایل، شماره خط، موقعیت ستون، نام تابع و سطح ریسک برابری داشته باشند.
خطاهای رمزگذاری نویسهها (Character Encoding Errors)
دستور flawfinder از قوانین رمزگذاری نویسه تعیینشده توسط Python استفاده میکند. گاهی اوقات کد منبع برخی از قوانین رمزگذاری را بهطور کامل رعایت نمیکند. اگر flawfinder را با Python 2 اجرا کنید، این عدم انطباقها معمولاً در عمل تأثیری بر روند پردازش نخواهند داشت.
با این حال، اگر flawfinder را با Python 3 اجرا کنید، این موضوع میتواند مشکلساز باشد. توسعهدهندگان Python 3 میخواهند تمام دنیا همیشه و همهجا از رمزگذاریها به صورت کاملاً دقیق استفاده کنند، و بهطور کلی میخواهند همه فقط از UTF-8 استفاده کنند. رمزگذاری UTF-8 بسیار عالی و بسیار محبوب است، اما دنیا معمولاً اهمیتی نمیدهد که توسعهدهندگان Python 3 چه میخواهند.
هنگام اجرای flawfinder با استفاده از Python 3، اگر هر فایل مبدأیی شامل هرگونه متن ناسازگار باشد، برنامه با خطای شدید متوقف خواهد شد (crash). این اتفاق حتی زمانی رخ میدهد که متن ناسازگار درون توضیحات (کامنتها) یا رشتهها باشد (جایی که اغلب اهمیتی ندارد). پایتون ۳ امکانات توکار مناسبی را برای مواجهه با بینظمیهای دنیای واقعی فراهم نمیکند، بنابراین برخورد با این مشکل بدون وابستگی به کتابخانههای خارجی (که سعی در پرهیز از آنها داریم) چندان ساده نیست.
نشانه این مشکل این است که flawfinder را اجرا کنید و با چنین پیام خطایی روبرو شوید:
Error: encoding error in ,1.c
'utf-8' codec can't decode byte 0xff in position 45: invalid start byte
آنچه مشاهده میکنید نتیجه یک خطای داخلی UnicodeDecodeError است.
اگر با این مشکل مواجه شدید، چندین گزینه وجود دارد:
گزینه شماره ۱ (حالت خاص): اگر سیستم شما معمولاً از رمزگذاری دیگری غیر از UTF-8 استفاده میکند، بهدرستی برای استفاده از آن رمزگذاری پیکربندی شده است (با استفاده از LC_ALL و شاید LC_CTYPE)، و فایلهای ورودی نیز با همان رمزگذاری غیر از UTF-8 هستند، ممکن است Python3 (به اشتباه) پیکربندی شما را نادیده گرفته باشد. در این حالت، با تنظیم متغیر محیطی PYTHONUTF8=0 به سادگی به Python3 بگویید از پیکربندی شما استفاده کند؛ به عنوان مثال flawfinder را به این صورت اجرا کنید: "PYTHONUTF8=0 python3 flawfinder ...".
گزینه شماره ۲ (حالت خاص): اگر میدانید رمزگذاری فایلها چیست، میتوانید استفاده از آن رمزگذاری را اجباری کنید. برای نمونه، اگر رمزگذاری BLAH است، flawfinder را به این صورت اجرا کنید: "PYTHONUTF8=0 LC_ALL=C.BLAH python3 flawfinder ...". میتوانید "C" پس از =LC_ALL را با لوکال واقعی زبان خود (مانند "en_US") جایگزین کنید.
گزینه شماره ۳: اگر نمیدانید رمزگذاری چیست، یا اینکه رمزگذاری ناسازگار است (مانند حالت معمول فایلهای UTF-8 که برخی از نویسههای آن با Windows-1252 رمزگذاری شدهاند)، میتوانید سیستم را وادار به استفاده از رمزگذاری ISO-8859-1 (Latin-1) کنید که در آن همه بایتها مجاز هستند. اگر ناسازگاریها صرفاً در توضیحات و رشتهها باشند و مجموعه نویسه زیربنایی «به اندازه کافی به ASCII نزدیک» باشد، این روش میتواند کار شما را بهسرعت راه بیندازد. میتوانید این کار را با اجرای دستور زیر انجام دهید: "PYTHONUTF8=0 LC_ALL=C.ISO-8859-1 python3 flawfinder ...". در برخی موارد ممکن است به "PYTHONUTF8=0" نیازی نداشته باشید. شاید بتوانید "C" پس از =LC_ALL را با لوکال واقعی زبان خود (مانند "en_US") جایگزین کنید.
گزینه شماره ۴: رمزگذاری فایلهای مورد تحلیل را به یک رمزگذاری واحد تبدیل کنید؛ اکیداً توصیه میشود که آنها را به UTF-8 تبدیل نمایید. برای مثال، از برنامه سیستمی "iconv" یا برنامه پایتونی cvt2utf میتوان برای تبدیل رمزگذاریها استفاده کرد. (میتوانید cvt2utf را با دستور "pip install cvtutf" نصب کنید). این روش در شرایطی مناسب است که برخی فایلها دارای یک نوع رمزگذاری و برخی دیگر دارای رمزی دیگر باشند، اما درون هر تکفایل یکپارچگی برقرار باشد. اگر فایلها دارای خطاهای رمزگذاری داخلی باشند، باید آنها را اصلاح کنید.
گزینه شماره ۵: اجرای flawfinder با استفاده از Python 2 به جای Python 3؛ مانند: "python2 flawfinder ...".
جهت شفافسازی: اکیداً توصیه میکنم از رمزگذاری UTF-8 برای تمام کدهای مبدأ استفاده کنید، و با بهرهگیری از آزمونهای ادغام مداوم (CI) اطمینان حاصل کنید که کد مبدأ همواره دارای رمزگذاری معتبر UTF-8 است. اگر این کار را انجام دهید، بسیاری از مشکلات ناپدید میشوند. اما در دنیای واقعی اوضاع همیشه به این صورت نیست. امید است این اطلاعات به شما در رویارویی با مشکلات رمزگذاری در دنیای واقعی کمک کند.
مثالها (EXAMPLES)
در ادامه مثالهای مختلفی از نحوه فراخوانی flawfinder آورده شده است. مثالهای ابتدایی گزینههای خط فرمان ساده و گوناگون را نشان میدهند. برنامه flawfinder طوری طراحی شده است که با ویرایشگرهای متنی و محیطهای توسعه یکپارچه (IDE) بهخوبی هماهنگ شود، بنابراین بخشهای بعدی نحوه ادغام flawfinder را با vim و emacs نمایش میدهند..SS "گزینههای ساده خط فرمان"
- flawfinder /usr/src/linux-3.16
- بررسی تمام فایلهای C/C++ در دایرکتوری /usr/src/linux-3.16 و تمام زیردایرکتوریهای آن (بهصورت بازگشتی)، و گزارش تمام یافتههای پیدا شده. بهطور پیشفرض، flawfinder از پیوندهای نمادین و دایرکتوریهایی که نام آنها با نقطه آغاز میشود صرفنظر میکند.
- flawfinder --error-level=4 .
- بررسی تمام فایلهای C/C++ در دایرکتوری جاری و زیردایرکتوریهای آن (بهصورت بازگشتی)؛ در صورتی که آسیبپذیریهایی با سطح ۴ و بالاتر (دو سطح با بالاترین خطر) وجود داشته باشند، یک کد خطا بازمیگرداند. این روشی مناسب برای استفاده از flawfinder در یک سیستم یکپارچهسازی مداوم است.
- flawfinder --minlevel=4 .
- بررسی تمام فایلهای C/C++ در دایرکتوری جاری و زیردایرکتوریهای آن (بهصورت بازگشتی)؛ تنها آسیبپذیریهای سطح ۴ و بالاتر (دو سطح با بالاترین خطر) را گزارش میدهد.
- flawfinder --inputs mydir
- بررسی تمام فایلهای C/C++ در mydir و زیردایرکتوریهای آن (بهصورت بازگشتی)، و گزارش توابعی که ورودی دریافت میکنند (تا بتوانید اطمینان حاصل کنید که ورودیها را بهطور مناسب پالایش میکنند).
- flawfinder --neverignore mydir
- بررسی تمام فایلهای C/C++ در دایرکتوری mydir و زیردایرکتوریهای آن، حتی شامل یافتههایی که در توضیحات کد برای نادیده گرفته شدن نشانهگذاری شدهاند.
- flawfinder --csv .
- بررسی دایرکتوری جاری به پایین (بهصورت بازگشتی)، و گزارش تمام یافتهها در قالب CSV. اگر میخواهید خروجی flawfinder را با استفاده از ابزارهای دیگر (مانند ابزارهای همبستگی دادهها) بیشتر پردازش کنید، این قالب توصیهشده است.
- flawfinder -QD mydir
- بررسی mydir و گزارش تنها نتایج واقعی (حذف سرآیند و پانویس خروجی). این فرم ممکن است زمانی مفید باشد که خروجی برای تحلیل بیشتر از طریق پایپ به ابزارهای دیگر هدایت شود، اگرچه در آن حالت احتمالاً قالب CSV انتخاب بهتری است. گزینههای -C (--columns) و -S (--singleline) نیز اگر دادهها را به ابزارهای دیگر پایپ میکنید، میتوانند مفید باشند.
- flawfinder -QDSC mydir
- بررسی mydir، با گزارش تنها نتایج واقعی (بدون سرآیند یا پانویس). هر یافته در یک خط گزارش میشود، و شماره ستونها نیز گزارش میگردند. این دستور زمانی که خروجی flawfinder را به ابزارهای دیگر میدهید میتواند مفید باشد.
- flawfinder --quiet --html --context mydir > results.html
- بررسی تمام فایلهای C/C++ در دایرکتوری mydir و زیردایرکتوریهای آن، و تولید نسخهای با قالببندی HTML از نتایج. سیستمهای مدیریت کد منبع (مانند SourceForge و Savannah) ممکن است از دستوری شبیه به این استفاده کنند.
- flawfinder --quiet --savehitlist saved.hits *.[ch]
- بررسی تمام فایلهای .c و .h در دایرکتوری جاری. وضعیت پردازش گزارش نمیشود، و فهرست یافتههای حاصل (مجموعه تمام یافتهها) در فایل saved.hits ذخیره میگردد.
- flawfinder --diffhitlist saved.hits *.[ch]
- بررسی تمام فایلهای .c و .h در دایرکتوری جاری، و نمایش هر یافتهای که از پیش در فایل saved.hits وجود نداشته است. اگر saved.hits از نسخه قدیمیتر برنامه تحت تحلیل ایجاد شده باشد، میتوان از این دستور برای نشان دادن تنها آسیبپذیریهای «جدید» در یک برنامه اصلاحشده استفاده کرد.
- flawfinder --patch recent.patch .
- بررسی دایرکتوری جاری بهصورت بازگشتی، اما فقط گزارش خطوطی که در وصلهفایلِ از پیش اعمالشده با نام recent.patch تغییر یافته یا افزوده شدهاند.
- flawfinder --regex "CWE-120|CWE-126" src/
- بررسی دایرکتوری src بهصورت بازگشتی، اما فقط گزارش یافتههایی که CWE-120 یا CWE-126 در مورد آنها صدق میکند.
فراخوانی از vim
ویرایشگر متن vim شامل یک سازوکار "quickfix" است که بهخوبی با flawfinder کار میکند، بهطوری که میتوانید بهآسانی پیامهای هشدار را مشاهده کرده و به کد منبع مربوطه پرش کنید.
ابتدا، باید flawfinder را فراخوانی کنید تا فهرستی از یافتهها ایجاد شود، و برای انجام این کار دو راه وجود دارد. راه نخست این است که ابتدا flawfinder را شروع کرده و سپس (با استفاده از خروجی آن) vim را فراخوانی کنید. راه دوم این است که vim را اجرا کرده (یا به اجرای آن ادامه دهید) و سپس flawfinder را فراخوانی نمایید (بهطور معمول از داخل vim).
برای راه نخست، flawfinder را اجرا کرده و خروجی آن را در یک FLAWFILE (مثلاً "flawfile") ذخیره کنید، سپس vim را با استفاده از گزینه -q آن فراخوانی نمایید، مانند این: "vim -q flawfile". راه دوم (شروع flawfinder پس از اجرای vim) میتواند به روشهای بیشماری انجام شود. یک راه، فراخوانی flawfinder با استفاده از یک دستور پوسته است، ":!flawfinder-command > FLAWFILE"، و سپس دنبال کردن آن با دستور ":cf FLAWFILE". راه دیگر این است که دستور flawfinder را در makefile خود ذخیره کنید (مثلاً به عنوان یک شبهدستور مانند "flaw")، و سپس ":make flaw" را اجرا نمایید.
در تمام این موارد، به دستوری برای اجرای flawfinder نیاز دارید. یک دستور مناسب، که هر یافته را در یک خط مجزا قرار میدهد (-S) و سرآیندها و پانویسهایی را که باعث سردرگمی میشوند حذف میکند، عبارت است از:
flawfinder -SQD .
اکنون میتوانید از دستورهای ویرایشی مختلف برای مشاهده نتایج استفاده کنید. دستور ":cn" یافته بعدی را نمایش میدهد؛ ":cN" یافته قبلی را نمایش میدهد، و ":cr" به نخستین یافته بازمیگردد. دستور ":copen" پنجرهای را برای نمایش فهرست فعلی یافتهها، موسوم به "quickfix window" (پنجره quickfix)، باز میکند؛ ":cclose" پنجره quickfix را میبندد. اگر بافر در پنجره استفادهشده تغییر کرده باشد و خطا در فایل دیگری باشد، پرش به خطا با شکست مواجه خواهد شد. باید پیش از تلاش برای پرش به یک فایل جدید، مطمئن شوید که پنجره حاوی بافری است که میتوان آن را نادیده گرفت، مثلاً با ذخیره کردن فایل؛ این کار از دست رفتن تصادفی دادهها جلوگیری میکند..SS "فراخوانی از emacs (Invoking from emacs)" ویرایشگر متن / سیستمعامل emacs شامل سازوکارهای «حالت grep» (grep mode) و «حالت compile» (compile mode) است که بهخوبی با flawfinder کار میکنند و مشاهده پیامهای هشدار، پرش به کد منبع مربوطه و رفع هر مشکلی که بیابید را آسان میسازند.
ابتدا، باید flawfinder را فراخوانی کنید تا فهرستی از پیامهای هشدار بسازد. میتوانید از «grep mode» یا «compile mode» برای ایجاد این فهرست استفاده کنید. اغلب «grep mode» راحتتر است؛ زیرا حالت کامپایل را دستنخورده رها میکند تا پس از ایجاد تغییرات، بتوانید بهآسانی دوباره کامپایل کنید. با این حال، اگر میخواهید دقیقاً به موقعیت ستون یک یافته بپرید، ممکن است compile mode راحتتر باشد، زیرا emacs میتواند از خروجی ستون flawfinder برای پرش مستقیم به موقعیت مناسب بدون نیاز به هیچ پیکربندی خاصی استفاده کند.
برای استفاده از grep mode، دستور “M-x grep” را وارد کنید و سپس دستور flawfinder مورد نظر را درج نمایید. برای استفاده از compile mode، دستور “M-x compile” را وارد کرده و دستور flawfinder مورد نظر را بنویسید. این یک دستور با کلید متا (meta key) است، بنابراین باید از کلید متا در صفحهکلید خود استفاده کنید (این کلید معمولاً کلید ESC است). همانند تمام دستورات emacs، پس از تایپ “grep” یا “compile” باید کلید RETURN را فشار دهید. بنابراین در بسیاری از سیستمها، grep mode با تایپ ESC x g r e p RETURN فراخوانی میشود.
سپس باید دستوری را وارد کنید و در صورت لزوم، آنچه را که از قبل آنجا بوده پاک نمایید. یک دستور معقول چنین است:
flawfinder -SQDC .
این دستور کاری میکند که هر مورد یافتشده در یک خط واحد گزارش شود، که مدیریت آن برای ابزارها بسیار سادهتر است. گزینههای quiet و dataonly سایر اطلاعات وضعیتی را که برای استفاده درون emacs مورد نیاز نیستند، حذف میکنند. نقطه در پایان دستور به این معناست که دایرکتوری جاری و تمام نوادگان (زیرشاخههای) آن برای کدهای C/C++ جستجو شده و برای آسیبپذیریها تحلیل میشوند.
پس از فراخوانی flawfinder، میتوانید از emacs برای جابهجایی درون نتایج آن استفاده کنید. دستور C-x ` (Control-x بکتیک) مکان کد منبع را برای پیام هشدار بعدی باز میکند. دستور C-u C-x ` (کلیدهای control-u control-x بکتیک) فرآیند را از ابتدا بازآغازی میکند. میتوانید با رفتن روی آن پیام خطا در بافر *compilation* یا بافر *grep* و فشردن کلید return، منبع مربوط به هر پیام خطای خاص را مشاهده کنید. (نکته فنی: در بافر compilation، این کار دستور compile-goto-error را فراخوانی میکند.) همچنین میتوانید روی پیام خطا با کلید Mouse-2 موشواره کلیک کنید (نیازی نیست ابتدا به بافر *compilation* بروید).
اگر میخواهید از grep mode برای پرش به ستونهای خاص یک یافته استفاده کنید، باید emacs را به طور ویژه برای این کار پیکربندی کنید. برای انجام این کار، متغیر emacs با نام “grep-regexp-alist” را تغییر دهید. این متغیر به Emacs میگوید که چگونه خروجی یک دستور “grep” را تجزیه کند، مشابه متغیر “compilation-error-regexp-alist” که قالبهای گوناگون پیامهای خطای کامپایل را فهرست میکند.
فراخوانی از محیطهای یکپارچه توسعه (Invoking from Integrated Development Environments - IDEs)
برای (سایر) IDEها، به مجموعه افزونههای (plug-ins) محیط توسعه خود مراجعه کنید.
شمارش ضعفهای رایج (COMMON WEAKNESS ENUMERATION - CWE)
سامانه شمارش ضعفهای رایج (Common Weakness Enumeration یا CWE) “فهرست یا واژهنامهای رسمی از ضعفهای رایج نرمافزاری است که میتوانند در معماری، طراحی، کد یا پیادهسازی نرمافزار رخ دهند و به آسیبپذیریهای امنیتی قابلسوءاستفاده منجر شوند... که به منظور زبانی مشترک برای توصیف ضعفهای امنیتی نرمافزار ایجاد شده است” (https://cwe.mitre.org/about/faq.html). برای اطلاعات بیشتر درباره CWEها، به https://cwe.mitre.org مراجعه کنید.
ابزار Flawfinder از CWE پشتیبانی میکند و رسماً سازگار با CWE (CWE-Compatible) است. توضیحات موارد یافتشده معمولاً حاوی شناسه مرتبط Common Weakness Enumeration (CWE) در داخل پرانتز هستند، در صورتی که CWE مرتبطی شناخته شده باشد. برای نمونه، بسیاری از یافتههای مرتبط با بافر به CWE-120 اشاره دارند؛ شناسه CWE برای “کپی بافر بدون بررسی اندازه ورودی” (معروف به “سرریز کلاسیک بافر” یا Classic Buffer Overflow). در موارد اندکی ممکن است بیش از یک شناسه CWE فهرست شود. گزارش HTML همچنین شامل پیوندهای ابرمتنی به تعاریف CWE میزبانیشده در MITRE است. به این ترتیب، flawfinder طوری طراحی شده است که نیازمندی CWE-Output را برآورده سازد.
در برخی موارد چالشهایی در نگاشت و استفاده از CWE وجود دارد؛ در اینجا نحوه مدیریت آنها توسط flawfinder آمده است. اگر یک مدخل به طور همزمان به چندین CWE نگاشت شود، تمامی نگاشتهای CWE با کاما از یکدیگر جدا شده و فهرست میشوند. این موضوع معمولاً در CWE-20 (اعتبارسنجی نامناسب ورودی) رخ میدهد؛ بنابراین گزارش “CWE-676, CWE-120” به دو CWE نگاشت میشود. علاوه بر این، flawfinder اطلاعات بیشتری را برای افرادی که به فهرست ۲۵ مورد برتر CWE/SANS در سال ۲۰۱۱ (https://cwe.mitre.org/top25) علاقهمندند در مواردی که نگاشتها مستقیماً به آنها نیست ارائه میدهد. بسیاری از افراد مایلند به جستجوی CWEهای خاصی در این فهرست ۲۵ مورد برتر بپردازند، مانند CWE-120 (سرریز کلاسیک بافر). چالش این است که برخی یافتههای flawfinder به یک CWE کلیتر نگاشت میشوند که شامل یک مورد از ۲۵ مورد برتر است، در حالی که در برخی موارد دیگر، یافتهها به آسیبپذیری خاصتری نگاشت میشوند که صرفاً زیرمجموعهای از یک مورد در ۲۵ مورد برتر است. برای برطرف کردن این مسئله، در برخی موارد flawfinder توالیای از CWEها را در قالب “more-general/more-specific” فهرست میکند، که در آن پس از CWEای که در واقع نگاشت شده است یک “!” قرار میگیرد. این کار همیشه زمانی انجام میشود که یک نقص مستقیماً به یک CWE در ۲۵ مورد برتر نگاشت نشده باشد، اما نگاشت به چنین CWEای مرتبط باشد. بنابراین “CWE-119!/CWE-120” بدان معناست که آسیبپذیری به CWE-119 نگاشت شده و CWE-120 زیرمجموعهای از CWE-119 است. در مقابل، “CWE-362/CWE-367!” بدین معناست که یافته به CWE-367، یعنی زیرمجموعهای از CWE-362 نگاشت شده است. توجه داشته باشید که این یک تغییر جزئی در نحو (syntax) نسبت به نسخه 1.31 نرمافزار flawfinder است؛ در نسخه 1.31 ابزار flawfinder، قالب “more-general:more-specific” به معنای چیزی بود که اکنون به شکل “more-general!/more-specific” فهرست میشود، در حالی که “more-general/more-specific” به معنای “more-general/more-specific!” بود. ابزارها در صورت تمایل میتوانند هر دو قالب نسخه 1.31 و قالب فعلی را پردازش کنند، با این توجه که در قالب قدیمیتر اصلاً از “!” استفاده نشده بود (و از این رو تشخیص آن آسان است). این سازوکارهای نگاشت، جستجو برای برخی CWEها را تسهیل میکنند.
نسخه 2.7 از CWE (منتشرشده در ۲۳ ژوئن ۲۰۱۴) برای نگاشت استفاده شده است. نگاشتهای فعلی CWE، دقیقترین و خاصترین CWEای را که ابزار بتواند مشخص کند برمیگزینند. از نظر نظری، بیشتر مؤلفههای امنیتی CWE (امضاها/الگوهایی که ابزار جستجو میکند) از لحاظ نظری میتوانستند به CWE-676 (استفاده از توابع بالقوه خطرناک) نگاشت شوند، اما چنین نگاشتی مفید نمیبود. بنابراین، هر جا که نگاشت خاصتری یافت میشد ترجیح داده شد. ابزار Flawfinder یک ابزار تحلیل لغوی (واژگانی) است؛ در نتیجه، عملاً غیرممکن است که بتواند دقیقتر از نگاشتهای پیادهسازیشده کنونی عمل کند. این همچنین بدان معناست که بعید است به بهروزرسانیهای مداوم برای تطابق با تغییرات CWE نیاز باشد؛ زیرا این ابزار اصولاً اطلاعات کافی برای ریز شدن تا سطح جزئیاتی از CWE که دستخوش دگرگونیهای معمول CWE میشود را ندارد. فهرست شناسههای CWE با استفاده از “make show-cwes” به طور خودکار تولید شده است، بنابراین اطمینان بالایی از صحت این فهرست وجود دارد. لطفاً در صورت مشاهده هرگونه مشکل در نگاشت CWE، آن را به عنوان باگ گزارش کنید.
ممکن است flawfinder در یافتن یک آسیبپذیری ناموفق باشد، حتی اگر flawfinder یکی از این ضعفهای CWE را پوشش دهد. با این وجود، flawfinder آسیبپذیریهای فهرستشده توسط CWEهایی که پوشش میدهد را پیدا میکند، و در بسیاری از موارد خطوط بدون آن آسیبپذیریها را گزارش نمیدهد. بنابراین، همانطور که برای هر ابزارِ مدعی سازگاری با CWE الزامی است، میزان مثبت کاذب (false positive) در flawfinder کمتر از ۱۰۰٪ و میزان منفی کاذب (false negative) آن نیز کمتر از ۱۰۰٪ است. ابزار Flawfinder تقریباً همیشه هرگاه تطابقی با یک مؤلفه امنیتی CWE (امضا/الگویی طبق تعریف پایگاهداده آن) بیابد آن را گزارش میکند، اگرچه ساختارهای مبهم خاصی میتوانند باعث عدم موفقیت آن شوند (بخش «گزارش باگها (BUGS)» در زیر را ببینید).
ابزار Flawfinder میتواند CWEهای زیر را گزارش کند (اینها CWEهایی هستند که flawfinder پوشش میدهد؛ علامت “*” نشاندهنده موارد موجود در فهرست ۲۵ مورد برتر CWE/SANS است):
- CWE-20: اعتبارسنجی نامناسب ورودی (Improper Input Validation)
- CWE-22: محدودسازی نامناسب نام مسیر به یک دایرکتوری محدودشده (“Path Traversal”)
- CWE-78: خنثیسازی نامناسب عناصر ویژه استفادهشده در یک دستور سیستمعامل (“OS Command Injection”)*
- CWE-119: محدودسازی نامناسب عملیات در محدوده یک بافر حافظه (والد *CWE-120، بنابراین به صورت CWE-119!/CWE-120 نشان داده میشود)
- CWE-120: کپی بافر بدون بررسی اندازه ورودی (“Classic Buffer Overflow”)*
- CWE-126: بیشخوانی بافر (Buffer Over-read)
- CWE-134: رشته قالببندی مهارنشده (Uncontrolled Format String)*
- CWE-190: سرریز یا چرخش عدد صحیح (Integer Overflow or Wraparound)*
- CWE-250: اجرا با دسترسیهای غیرضروری (Execution with Unnecessary Privileges)
- CWE-327: استفاده از الگوریتم رمزنگاری شکسته یا پرخطر (Use of a Broken or Risky Cryptographic Algorithm)*
- CWE-362: اجرای همروند با استفاده از منبع مشترک با همگامسازی نامناسب (“Race Condition”)
- CWE-377: فایل موقت ناامن (Insecure Temporary File)
- CWE-676: استفاده از تابع بالقوه خطرناک (Use of Potentially Dangerous Function)*
- CWE-732: تخصیص نادرست مجوز برای منبع حیاتی (Incorrect Permission Assignment for Critical Resource)*
- CWE-785: استفاده از تابع دستکاری مسیر بدون بافر با حداکثر اندازه (فرزند *CWE-120، بنابراین به صورت CWE-120/CWE-785 نشان داده میشود)
- CWE-807: اتکا به ورودیهای غیرقابلاعتماد در تصمیمگیری امنیتی (Reliance on Untrusted Inputs in a Security Decision)*
- CWE-829: گنجاندن قابلیتها از حوزه کنترلی غیرقابلاعتماد (Inclusion of Functionality from Untrusted Control Sphere)*
میتوانید با استفاده از گزینه “--regex” (-e)، زیرمجموعه خاصی از CWEها را برای گزارش انتخاب کنید. این گزینه یک عبارت باقاعده (regular expression) میپذیرد، بنابراین میتوانید چندین CWE را انتخاب نمایید، برای مثال: “--regex "CWE-120|CWE-126"”. اگر چندین CWE را با “|” در یک خط فرمان انتخاب کنید، معمولاً باید پارامترها را داخل علامت نقلقول قرار دهید (زیرا علامت “|” بدون نقلقول، نماد لوله است). ابزار Flawfinder طوری طراحی شده است که نیازمندی CWE-Searchable را برآورده سازد..PP اگر هدف شما گزارش زیرمجموعهای از CWEهایی است که در یک فایل فهرست شدهاند، این کار در یک سیستم شبهیونیکس با استفاده از گزینهٔ «--regex» (یا همان «-e») امکانپذیر است. فایل ورودی باید در قالب عبارت منظم (regular expression) باشد. به عنوان مثال، دستور «flawfinder -e $(cat file1)» تنها مواردی را گزارش میدهد که با الگوی درون «file1» مطابقت داشته باشند. اگر file1 حاوی «CWE-120|CWE-126» باشد، فقط تطابقهای مربوط به این CWEها گزارش خواهند شد.
فهرست کاملی از تمامی عناصر امنیتی CWE (امضاها یا الگوهایی که flawfinder بهدنبال آنها میگردد) را میتوان با استفاده از گزینهٔ «--listrules» مشاهده کرد. هر خط شامل نشانهٔ امضا (عموماً یک نام تابع) است که ممکن است به یک مورد تطابق منجر شود، به همراه سطح خطر پیشفرض، و هشدار پیشفرض (که شامل شناسهٔ پیشفرض CWE است). برای بیشتر اهداف، اگر بخواهید ببینید کدام عناصر امنیتی به کدام CWEها نگاشت میشوند یا برعکس، این گزینه کافی است. به عنوان مثال، برای دیدن اکثر امضاها (نامهای تابع) که به CWE-327 نگاشت میشوند، بدون دیدن سطح خطر پیشفرض یا متن تفصیلی هشدار، دستور زیر را اجرا کنید: «flawfinder --listrules | grep CWE-327 | cut -f1». همچنین میتوانید با اجرای «flawfinder -D --listrules | grep -v CWE-» نشانههای فاقد نگاشت CWE را مشاهده کنید. با این حال، هرچند --listrules تمامی عناصر امنیتی CWE را فهرست میکند، اما فقط نگاشتهای پیشفرض از عناصر امنیتی CWE به شناسههای CWE را نشان میدهد. این فهرست شامل پالایشها و جزئیاتی که flawfinder اعمال میکند (برای نمونه با بررسی پارامترهای تابع) نمیشود.
اگر خواستار نگاشت دقیق و با جزئیات کامل بین عناصر امنیتی CWE و شناسههای CWE هستید، کد منبع flawfinder (موجود در توزیع نرمافزار) بهترین مرجع برای این اطلاعات است. این اطلاعات تفصیلی عمدتاً برای آن دسته از افراد معدودی مفید است که در پی بهبود و پالایش نگاشتهای CWE در flawfinder یا خود ساختار CWE بهطور کلی هستند. کد منبع نگاشت میان عناصر امنیتی و شناسههای CWE مربوطه را مستند کرده و در قالب یک تکفایل Python ارائه شده است. مجموعهدادهٔ «c_rules» بیشتر قوانین را به همراه ارجاع به تابعی که میتواند پالایشهای بیشتری اعمال کند، تعریف میکند. میتوانید در این مجموعهداده نام توابع را جستجو کنید تا ببینید بهطور پیشفرض چه CWEای تولید میکنند؛ اگر پارامتر نخست برابر با «normal» نباشد، نام یک متد پایتونی برای پالایش است که ممکن است بسته به اطلاعات تکمیلی، CWEهای متفاوتی را انتخاب کند. برعکس، میتوانید عبارت «CWE-number» را جستجو کنید تا ببینید کدام عناصر امنیتی (امضاها یا الگوها) به آن شناسهٔ CWE اشاره دارند. برای بیشتر افراد، این سطح از جزئیات بسیار فراتر از نیازشان است؛ اغلب کاربران صرفاً میخواهند کد منبع خود را برای یافتن سریع مشکلات پویش کنند.
امنیت (SECURITY)
تمام هدف این ابزار کمک به یافتن آسیبپذیریهاست تا بتوان آنها را برطرف کرد. با این وجود، توسعهدهندگان و بازبینها باید بدانند چگونه نرمافزار امن توسعه دهند تا بتوانند از این ابزار استفاده کنند؛ چرا که در غیر این صورت، یک نادان با یک ابزار، همچنان یک نادان است. کتاب من در https://dwheeler.com/secure-programs ممکن است در این زمینه کمککننده باشد.
این ابزار در نهایت باید بخش کوچکی از یک فرایند گستردهتر توسعهٔ نرمافزار باشد که برای حذف یا کاهش اثرات آسیبپذیریها طراحی شده است. توسعهدهندگان و بازبینها نیاز دارند شیوهٔ تولید نرمافزار امن را بدانند و باید این دانش را به کار ببندند تا در وهلهٔ اول، خطرات ناشی از آسیبپذیریها کاهش یابد.
ابزارهای گوناگونِ کشفِ آسیبپذیری تمایل دارند آسیبپذیریهای متفاوتی را کشف کنند. از این رو، بهترین راهکار این است که از بازبینی انسانی همراه با ابزارهای متنوع استفاده کنید. این ابزار میتواند به یافتن برخی آسیبپذیریها کمک کند، اما به هیچ وجه تمامی آنها را کشف نخواهد کرد.
توجه داشته باشید که flawfinder اساساً برای یافتن آسیبپذیریهای غیرعمدی (اشتباهات رایج) از طریق جستجوی الگوهای خاص طراحی شده است. در نتیجه، احتمال کشف کدهای مخرب (مانند اسبهای تروا) که بهطور عامدانه اضافه شدهاند، توسط این ابزار بسیار کمتر است. برنامهنویسان بدخواه میتوانند بهراحتی کدی را بگنجانند که توسط چنین ابزارهایی شناسایی نشود. این ابزار فقط باید برای یافتن آسیبپذیریهای غیرعمدی استفاده شود؛ روشهای دیگر (مانند بازبینی دقیق و انسانی تمام تغییرات) برای شناسایی کدهای عامدانه مخرب مورد نیاز است. (میتوانید برای تحلیل کدهای مخرب از هوش مصنوعی استفاده کنید، اما هشیار باشید که چنین کدهایی ممکن است شامل تزریقهای ویژه به هوش مصنوعی باشند که میتوانند کارایی هوش مصنوعی را مختل کرده یا آن را مخرب سازند.)
شما همواره باید یک نسخهٔ کپی از برنامهٔ مبدأ مورد نظر را تحلیل کنید، نه دایرکتوریای که حین تحلیل flawfinder بتواند توسط یک توسعهدهنده ویرایش شود. این مسئله بهویژه زمانی صدق میکند که شما لزوماً به توسعهدهندهٔ برنامهٔ مورد تحلیل اعتماد کامل ندارید. چنانچه مهاجمی در حین بررسی فایلها بر آنها کنترل داشته باشد، میتواند فایلها را جابهجا کرده یا محتوای آنها را تغییر دهد تا از افشای یک رخنهٔ امنیتی جلوگیری کند (یا باعث ایجاد تصوری کاذب از وجود مشکل در جایی که مشکلی نیست شود). اگر نگران برنامهنویسان مخرب هستید باید در هر صورت این شیوه را پیش بگیرید، چرا که پس از پایان تحلیل باید تأیید کنید کدی که در نهایت اجرا میشود دقیقاً همان کدی است که تحلیل کردهاید. همچنین، در چنین شرایطی هرگز از گزینهٔ --allowlink استفاده نکنید؛ مهاجمان میتوانند پیوندهای نمادین مخربی به فایلهای خارج از محدودهٔ کد منبع خود (مانند /etc/passwd) ایجاد کنند.
سیستمهای مدیریت کد منبع (مانند GitHub، SourceForge و Savannah) قطعاً مشمول این موضوع هستند؛ اگر مدیریت چنین سیستمهایی را بر عهده دارید، ابتدا فایلها را در یک دایرکتوری مجزا (که توسط مهاجمان قابل دستکاری نباشد) کپی یا استخراج کرده و سپس flawfinder یا هر ابزار تحلیل کد دیگری را اجرا کنید.
توجه داشته باشید که flawfinder تنها فایلهای عادی، دایرکتوریها و (در صورت درخواست) پیوندهای نمادین را باز میکند؛ این ابزار هرگز فایلهای دیگر را باز نخواهد کرد، حتی اگر پیوند نمادینی به آنها ایجاد شده باشد. این سازوکار مانع فعالیت مهاجمانی میشود که انواع فایلهای نامتعارف را در کد منبع قرار میدهند. با این حال، همانطور که پیشتر اشاره شد، این تدبیر تنها در حالتی مؤثر است که سیستمفایل مورد بررسی حین تحلیل توسط مهاجم قابل دستکاری نباشد. متأسفانه این لایهٔ حفاظتی در بستر سکوهای Cygwin نیز کارایی ندارد.
سیستمهای Cygwin (شبیهساز یونیکس روی Windows) در صورتی که flawfinder برای تحلیل برنامههای غیرقابل اعتماد به کار رود، دچار یک مشکل مضاعف هستند. این مشکل به یک نقص طراحی در Windows مربوط میشود (که از MS-DOS به ارث رسیده است). در Windows و MS-DOS، نام برخی فایلها (مانند «com1») بهطور خودکار توسط سیستمعامل به عنوان نام دستگاههای جانبی تفسیر میشود، و این موضوع حتی هنگام ارائهٔ مسیر کامل (full pathname) نیز رخ میدهد. بله، متأسفانه Windows و MS-DOS واقعاً تا این حد ضعیف طراحی شدهاند. Flawfinder با بررسی نوع شیء موجود در سیستمفایل و سپس باز کردن انحصاری دایرکتوریها و فایلهای عادی (و پیوندهای نمادین در صورت فعال بودن) این مسئله را مهار میکند. متأسفانه این راهکار روی Cygwin کارساز نیست؛ در برخی نگارشهای Cygwin روی برخی از نسخههای Windows، صرف تلاش برای تعیین اینکه آیا یک فایل نوعی دستگاه است یا خیر، میتواند سبب قفل شدن (hang) برنامه شود. یک راهکار جایگزین این است که پیش از اجرای تحلیل، هر فایلی را که به عنوان نام دستگاه تلقی میشود، حذف کرده یا تغییر نام دهید. این نامها که به «نامهای رزرو شده» معروفند عبارتند از: CON، PRN، AUX، CLOCK$، NUL، COM1-COM9 و LPT1-LPT9، که ممکن است پسوندی هم به آنها اضافه شده باشد (مانند «com1.txt»)، در هر دایرکتوری، و با هر ترکیبی از حروف کوچک و بزرگ (چرا که ویندوز به کوچکی و بزرگی حروف حساس نیست).
فهرستهای تطابق ذخیرهشده (hitlists) برای استفادهٔ همان کاربری در نظر گرفته شدهاند که آنها را تولید کرده است. یک فهرست تطابق از منبعی ناشناس و غیرقابل اعتماد میتواند نتایجی گمراهکننده، از جمله موارد تطابق ساختگی یا یافتههای پنهانشده داشته باشد؛ همیشه از فهرستهایی استفاده کنید که شخصاً ایجاد کردهاید. فهرستهای تطابق در قالب «pickle» پایتون ذخیره میشوند. Flawfinder اکنون تمهیداتی را برای مسدود کردن محتوای مخرب فهرستهای تطابق اتخاذ کرده است (هرچند نسخههای قدیمی فاقد آن بودند). با این وجود، flawfinder قادر به تشخیص فهرستهایی که محتوای نادرست اما از دید ساختاری معتبر دارند، نیست..SH "گزارش باگها (BUGS)"
ابزار Flawfinder بر پایهٔ تطبیق سادهٔ الگوهای متنی کار میکند که بخشی از طراحی بنیادین آن بوده و تغییر آن آسان نیست. این رویکرد طراحی منجر به شماری از محدودیتهای اساسی میشود، برای نمونه نرخ بالاتر مثبت کاذب (false positive)، و دلیل اصلی بیشتر باگهای فهرستشده در اینجا است. از سوی دیگر، Flawfinder با بسیاری از توالیهای پیچیدهٔ پیشپردازنده که گاهی ابزارهای دیگر را متوقف میکند، سردرگم نمیشود؛ Flawfinder اغلب میتواند کدهایی را پردازش کند که پیوند (link) نمیشوند، و حتی گاهی کامپایل یا ساخته (build) نیز نمیشوند.
ابزار Flawfinder در حال حاضر به C/C++ محدود است. علاوه بر این، هنگام تحلیل C++، تمرکز آن در درجهٔ اول بر زیرمجموعهٔ C در C++ است. برای نمونه، Flawfinder عباراتی مانند cin >> charbuf را که در آن charbuf یک آرایهٔ char است گزارش نمیکند. این به این دلیل است که Flawfinder اطلاعات نوع (type information) ندارد، و «>>» با بسیاری از انواع دادههای دیگر امن است؛ گزارش دادن تمام موارد «>>» منجر به مثبتهای کاذب بسیار زیادی میشود. با این وجود، بهگونهای طراحی شده است که افزودن پشتیبانی از زبانهای دیگر در جاهایی که رویکرد مبتنی بر متن آن بتواند بهطور مفیدی اعمال شود، آسان باشد.
توابع یا نامهای متد تعریفشده توسط کاربر که برحسب اتفاق مشابه مواردی باشند که در پایگاهدادهٔ آن بهعنوان “hits” تعریف شدهاند، میتوانند Flawfinder را فریب دهند و این ابزار اغلب روی تعاریف (و همچنین استفادههای) توابع همنام فعال میشود. این موضوع معمولاً برای کدهای C مشکلی ایجاد نمیکند. در کدهای C، تابعی با نام مشابهِ یک روال متداول در کتابخانه، اغلب نشاندهندهٔ این است که توسعهدهنده صرفاً در حال بازنویسی یک روال کتابخانهای رایج با همان رابط است (مثلاً به منظور قابلیت حمل). برنامههای C تمایل دارند از استفادهٔ مجدد از نام یکسان برای اهداف متفاوت خودداری کنند (زیرا در C نام توابع بهطور پیشفرض سراسری هستند). احتمال معقولی وجود دارد که این روالهای بازنویسیشده در معرض همان سوءاستفادهها باشند، و بنابراین، اعمال مجدد این قوانین رویکردی منطقی است. با این حال، این امر میتواند در کدهای C++ که بهشدت از کلاسها و فضاهای نام (namespaces) استفاده میکنند، مشکل بسیار جدیتری باشد، زیرا ممکن است یک نام متد معانی بسیار متفاوتی داشته باشد. گزینهٔ --falsepositive در این حالت تا حدی میتواند کمک کند. اگر این مشکل جدی است، میتوانید برنامه را تغییر دهید یا خروجی Flawfinder را با ابزارهای دیگر پردازش کنید تا موارد مثبت کاذب حذف شوند.
دستورات پیشپردازندهای که در میان فهرست پارامترهای یک فراخوانی قرار گرفتهاند میتوانند مشکلاتی در تجزیه (parsing) ایجاد کنند؛ بهویژه اگر یک رشته با استفاده از ساختار #ifdef .. #else چندین بار باز و سپس بسته شود، Flawfinder سردرگم خواهد شد. چنین ساختارهایی شیوهٔ کدنویسی نامناسبی تلقی میشوند و بسیاری از ابزارهای دیگر را نیز سردرگم میکنند. اگر ناچار به تحلیل چنین فایلهایی هستید، آن خطوط را بازنویسی کنید. خوشبختانه این موارد بسیار نادر هستند.
ابزار Flawfinder آسیبپذیریها را بدون در نظر گرفتن پارامترهای «#if» یا «#ifdef» گزارش میکند. یک ساختار «#if VALUE» در برخی موارد مقدار VALUE برابر با 0 خواهد داشت و در موارد دیگر مقداری غیر از صفر. بهطور مشابه، در «#ifdef VALUE» مقدار VALUE در برخی موارد تعریف شده و در موارد دیگر تعریفنشده است. ابزار Flawfinder در تمام این موارد گزارش میدهد، که بدان معناست Flawfinder فرصت گزارش آسیبپذیریها را در تمام حالتهای جایگزین دارد. این یک باگ نیست، بلکه رفتار در نظر گرفتهشده برای برنامه است.
ابزار Flawfinder موارد را حتی در صورتی که میان عبارات تحتاللفظی «#if 0» و «#endif» قرار گرفته باشند گزارش میکند. تغییر این وضعیت خاص امکانپذیر است، اما استفادهٔ مستقیم از «#if 0» برای غیرفعال کردن کد (بهصورت کامنت، بجز در هنگام اشکالزدایی) نشاندهندهٔ یکی از این دو است: (۱) حذف بسیار موقتی است (که در این صورت همچنان باید گزارش شود) یا (۲) شیوهٔ بسیار نامناسبی در کدنویسی است. اگر میخواهید برای همیشه از شر یک کد خلاص شوید، به جای استفاده از «#if 0» آن را حذف کنید، زیرا همیشه میتوانید با استفاده از نرمافزار کنترل نسخهٔ خود ببینید که آن کد چه بوده است. اگر از نرمافزار کنترل نسخه استفاده نمیکنید، پس این همان باگی است که باید همین حالا آن را رفع کنید.
برخی ساختارهای پیچیده یا نامعمول میتوانند Flawfinder را گمراه کنند. بهویژه اگر پارامتری با gettext(" آغاز شود و با ) پایان یابد، Flawfinder فرض خواهد کرد که پارامتر gettext یک مقدار ثابت است. این بدان معناست که با الگوهایی مانند gettext("hi") + function("bye") سردرگم خواهد شد. در عمل، به نظر نمیرسد این مورد مشکلی ایجاد کند؛ زیرا معمولاً gettext() کل پارامتر را در بر میگیرد.
روال تشخیص آرایههای نویسهای (character arrays) تعریفشده بهصورت ایستا (statically defined) از تطبیق متنی ساده استفاده میکند؛ برخی عبارات پیچیده میتوانند موجب شوند که این روال بهطور غیرمنتظرهای فعال شود یا فعال نشود.
ابزار Flawfinder به دنبال الگوهای خاصی میگردد که بهعنوان اشتباهات متداول شناخته شدهاند. ابزار Flawfinder (یا هر ابزار مشابه آن) برای یافتن کدهای مخرب عمدی (مانند اسبهای تروجان) ابزار مناسبی نیست؛ برنامهنویسان مخرب بهراحتی میتوانند کدهایی درج کنند که توسط این نوع ابزارها شناسایی نشوند.
ابزار Flawfinder به دنبال الگوهای خاصی میگردد که بهعنوان اشتباهات متداول در کدهای سطح کاربردی (application code) شناخته میشوند. بنابراین، احتمالاً در تحلیل برنامههایی که کدهای لایهٔ کاربردی نیستند (مانند کدهای هسته یا کدهای خودمیزبان) اثربخشی کمتری خواهد داشت. با این حال ممکن است این روشها همچنان مفید باشند؛ اگر شرایط شما تفاوت قابلتوجهی با حالت معمول دارد، میتوانید پایگاهداده را جایگزین کنید.
قالب خروجی پیشفرض Flawfinder (بهصورت filename:linenumber، و بهطور اختیاری به دنبال آن یک :columnnumber) در صورتی که فایلهای مبدأ نامهای بسیار عجیبی داشته باشند، ممکن است به اشتباه تفسیر شود. نام فایلهایی که حاوی نویسهٔ خط جدید/newline یا linefeed هستند باعث شکستگیهای عجیب میشوند، و نام فایلهای شامل دونقطه (:) احتمالاً نادرست تفسیر خواهند شد. این امر بهویژه زمانی اهمیت دارد که خروجی Flawfinder توسط ابزارهای دیگر مانند فیلترها یا ویرایشگرهای متن استفاده شود. اگر از خروجی Flawfinder در ابزارهای دیگر استفاده میکنید، استفاده از قالب CSV آن را مد نظر قرار دهید (که میتواند این موارد را مدیریت کند). اگر کدهای جدید را بررسی میکنید، فایلها را از نظر وجود چنین نویسههایی بررسی کنید. به هر حال داشتن چنین نامهایی برای فایلها بسیار نامعقول است؛ بسیاری از ابزارها اصلاً نمیتوانند با چنین نامهایی کار کنند. خط جدید (newline) و linefeed اغلب بهعنوان جداکنندهٔ داخلی دادهها استفاده میشوند. دونقطه اغلب بهعنوان نویسهٔ خاص در سیستمهای فایل استفاده میشود: سیستمعامل MacOS از آن بهعنوان جداکنندهٔ دایرکتوری استفاده میکند، Windows/MS-DOS از آن برای شناسایی حروف درایو استفاده میکند، Windows/MS-DOS بهطور متناقض از آن برای شناسایی دستگاههای خاص مانند CON: استفاده میکند، و برنامهها در بسیاری از پلتفرمها از دونقطه برای شناسایی URIها/URLها استفاده میکنند. نامهای فایلی که شامل فاصله (space) یا تب (tab) هستند مشکلی برای Flawfinder ایجاد نمیکنند، اگرچه توجه داشته باشید که ابزارهای دیگر ممکن است با آنها دچار مشکل شوند.
ابزار Flawfinder بینالمللیسازی نشده است، بنابراین در حال حاضر از بومیسازی (localization) پشتیبانی نمیکند.
بهطور کلی، Flawfinder تلاش میکند جانب احتیاط را رعایت کند؛ تمایل دارد موارد یافتهشده را گزارش دهد تا بتوان آنها را بیشتر بررسی کرد، نه اینکه بیسر و صدا آنها را نادیده بگیرد. بنابراین، Flawfinder ترجیح میدهد موارد مثبت کاذب (گزارشهایی که معلوم میشود مشکلی نیستند) داشته باشد تا موارد منفی کاذب (عدم گزارش آسیبپذیریهای امنیتی). اما این یک کلیت است؛ Flawfinder از روشهای اکتشافی ساده استفاده میکند و بهسادگی نمیتواند همه چیز را «درست» تشخیص دهد.
ممکن است آسیبپذیریهای امنیتی توسط Flawfinder بهعنوان آسیبپذیری شناسایی نشوند، و برعکس، برخی از موارد یافتهشده در واقع آسیبپذیریهای امنیتی نیستند. این امر در مورد تمام پویشگرهای امنیتی ایستا صدق میکند، و بهویژه در مورد ابزارهایی مانند Flawfinder صادق است که از تحلیل واژگانی و تحلیل الگوی ساده برای شناسایی آسیبپذیریهای احتمالی استفاده میکنند. با این وجود، میتواند بهعنوان یک ابزار کمکی مفید برای انسانها عمل کند و در شناسایی نقاط مناسب برای بررسی بیشتر یاری رساند، و این همان هدف این ابزار ساده است..SH "همچنین ببینید (SEE ALSO)" به وبسایت flawfinder در https://dwheeler.com/flawfinder مراجعه کنید. همچنین نگاه کنید به Secure Programming HOWTO در https://dwheeler.com/secure-programs.
نویسنده (AUTHOR)
David A. Wheeler (dwheeler@dwheeler.com).
| 3 May 2026 | Flawfinder |