برنامه‌نويسی امن با زبان C – پيش پردازشگرها

برنامه‌نويسی امن با زبان C – پيش پردازشگرها

تاریخ ایجاد

IRCAR201006067
عنصر اصلي در كدنويسي امن با زبان هاي مختلف برنامه نويسي، مستند سازي خوب و استفاده از استانداردهاي قابل اجرا است. استانداردهاي كدنويسي، برنامه نويسان را ترغيب به پيروي از مجموعه اي واحد از قوانين و راهنماييها مي كند كه بر اساس نيازمندي هاي پروژه و سازمان تعيين شده است، نه بر اساس سلايق و مهارت هاي مختلف برنامه نويسان. به محض تعيين استانداردهاي مذكور، مي توان از آن به عنوان معياري براي ارزيابي كدهاي منبع، چه به صورت دستي و چه به صورت اتوماتيك استفاده كرد. از استانداردهاي معروف در اين زمينه مي توان به استانداردCERT براي كدنويسي امن اشاره كرد كه يك سري از قوانين و پيشنهادات را براي كد نويسي امن با زبان هاي برنامه نويسي C، C++ و جاوا ارائه مي دهد. هدف از اين قوانين و پيشنهادات، حذف عادت هاي كدنويسي ناامن و رفتارهاي تعريف نشده است كه منجر به آسيب پذيري هاي قابل سوءاستفاده مي شود. به كارگيري استانداردهاي مذكور منجر به توليد سيستم هايي با كيفيت بالاتر مي شود كه در برابر حملات بالقوه، پايدارتر و مقاوم تر هستند. در مقاله "آشنايي با استاندارد CERT براي برنامه نويسي امن"، كليات استاندارد CERT در زمينه مزبور را توضيح داديم و در اين مقاله به صورت تخصصي تر شيوه برنامه نويسي امن با زبان C را مورد بررسي قرار مي دهيم. قابل ذكر است كه در اين استاندارد 89 قانون و 132 پيشنهاد براي برنامه نويسي امن با زبان C ارائه شده است كه در سري مقالات كدنويسي امن با زبان C، مهمترين آنها را كه در سطح يك قرار دارند، شرح خواهيم داد. براي كسب اطلاعات بيشتر در مورد سطح بندي قوانين و پيشنهادات به مقاله "آشنايي با استاندارد CERT براي برنامه نويسي امن" مراجعه فرماييد.

حوزه استاندارد CERT براي كدنويسي امن با C
استاندارد CERT براي كد نويسي امن با زبان برنامه نويسي C، به طور اختصاصي براي نسخه هايي كه توسط موسسات زير تعريف شده اند، تهيه شده است:

  • ISO/IEC 9899:1999 ويرايش دوم براي زبان C
  • Technical corrigenda TC1, TC2 and TC3
  • گسترش ISO/IEC TR 24731-1 براي كتابخانه C، قسمت اول: رابط هاي كاربر Bounds-checking
  • گسترش ISO/IEC PDTR 24731-2 براي كتابخانه C، قسمت دوم: Dynamic Allocation Functions

البته بسياري از موارد مطرح شده در اين استاندارد، قابليت اعمال بر نسخه هاي قديمي تر C را نيز دارد. همچنين هر چند كه بهترين راه حل ها براي مشكلات كدنويسي امن غالباً وابسته به سكو هستند، اما استاندارد مذكور مستقل از سيستم عامل و سكو است. البته در بسياري از موارد، استاندارد  CERT براي كدنويسي امن با C با سيستم هاي ويندوز و POSIX سازگاري دارد و همچنين در برخي از موارد داراي راه حل هاي اختصاصي براي سكوهايي همچون لينوكس و OpenBSD است.

دسته بندي قوانين و پيشنهادات
قوانين و پيشنهادات برنامه نويسي امن با زبان C به 14 زيرگروه تقسيم مي شوند. در زير دسته بندي مذكور و تعداد قوانين و پيشنهادات ارائه شده در هر زيرگروه آورده شده است.
 

c language

در ادامه قوانين و پيشنهادات سطح يك (L1) از هر بخش را توضيح مي دهيم.


Preprocessor) PRE)

1. پيشنهاد PRE01-C
درون ماكروها، پرانتز به دور نام پارامترها قرار دهيد. براي مثال كد زير با اين پيشنهاد همخواني ندارد:

#define CUBE(I) (I * I * I)

براي همخواني با پيشنهاد مذكور بايد آن را به شكل زير تغيير داد:

#define CUBE(I) ( (I) * (I) * (I) )

2. پيشنهاد PRE02-C
ليست هاي جايگزيني ماكروها بايد داراي پرانتز باشند. در زير نمونه اي را كه از پيشنهاد مذكور پيروي نكرده است مشاهده مي كنيد:

#define CUBE(X) (X) * (X) * (X)

براي همخواني با پيشنهاد مذكور بايد آن را به شكل زير تغيير داد:

#define CUBE(X) ((X) * (X) * (X))

3. پيشنهاد PRE09-C
نام توابع امن را با نام توابع قديمي (deprecated) مانند gets() و يا از پيش ذخيره شده (obsolescent) مانند strcpy() جايگزين نكنيد. يكي از كاربردهاي ماكروها، اصلاح يك كد موجود جهت جايگزيني يك شناسه با شناسه ديگر است. براي مثال براي تغيير API هاي موجود مي توان از ماكروها استفاده كرد. با وجودي كه همواره خطراتي همراه با اين كار وجود دارد، اما اين روش زماني واقعاً خطرناك مي شود كه نام يك تابع با نام توابعي كه در زير آمده است، جايگزين شود.

4. پيشنهاد PRE10-C
در صورتي كه بيش از يك دستور در ماكرو وجود دارد، آن را درون حلقه do-while قرار دهيد. به اين ترتيب ماكروها مي توانند به صورت امن در درون دستورات شرطي ( if clauses ) يا ديگر مكان هايي كه بايد دستورات درون ماكرو به صورت يك كل ديده شود، قرار گيرند.

#define SWAP(x, y)
do {
tmp = x;
x = y;
y = tmp; }
while (0)

5. پيشنهاد PRE11-C
در انتهاي ماكروها علامت ";" را قرار ندهيد. ماكروها معمولاً براي بالا بردن قابليت خوانايي كد منبع مورد استفاده قرار مي گيرند. دقت داشته باشيد كه ماكروها صرف نظر از اينكه داراي تنها يك دستور و يا بيشتر باشند نبايد با علامت "; " تمام شوند. اضافه كردن ";" در انتهاي ماكروها به صورت غيرمنتظره روند اجراي برنامه را تغيير مي دهد. براي مثال، در كد زير در حالي كه برنامه نويس انتظار سه بار چاپ "inside for loop" را دارد ولي به علت وجود ";" روند اجراي برنامه تغيير كرده و متن مزبور تنها يك بار در خروجي چاپ مي شود.

#define FOR_LOOP(n) for(i=0; i<(n); i++);>
int i;
FOR_LOOP(3)
{
puts("Inside for loopn"); }

براي اصلاح كد مزبور كافي است كه علامت ";" از انتهاي تعريف ماكرو برداشته شود.
در قسمت بعدي سري مقالات "برنامه نويسي امن با زبان C"، پيشنهادات و قوانين سطح 1 زير گروه هاي Expressions(EXP) و Integers(INT) را بررسي خواهيم كرد.

برچسب‌ها