امروزه در دنیا وابستگی کسبوکارها. سازمانها به نرمافزار و سیستمهای کامپیوتری روزبهروز بیشتر میشود، ازاینرو انتشار اپلیکیشنهای ایمن به اولویت اصلی توسعهدهندگان تبدیل شده است. خبر خوب این است که با نوشتن کد منبع (surce code) بهتر و ایمنتر میتوان از بسیاری از سوءاستفادهها و حملات بالقوه جلوگیری کرد.
`rm -rf /`
کدنویسی امن (Secure Coding) چیست؟
امروزه در دنیا وابستگی کسبوکارها. سازمانها به نرمافزار و سیستمهای کامپیوتری روزبهروز بیشتر میشود، ازاینرو انتشار اپلیکیشنهای ایمن به اولویت اصلی توسعهدهندگان تبدیل شده است. خبر خوب این است که با نوشتن کد منبع (surce code) بهتر و ایمنتر میتوان از بسیاری از سوءاستفادهها و حملات بالقوه جلوگیری کرد.
کدنویسی امن اصول طراحی کدی است که با شیوههای بهینه امنیتی نوشته شده است. اصولی که از کد منتشر شده در برابر آسیبپذیریهای شناخته شده، ناشناخته و غیرمنتظره مانند اکسپلویتهای امنیتی محافظت میکند.
آشنایی با تهدیدات امنیتی و مقابله با آن در سطح کد منبع یکی از لایههای امنیتی مهم در چرخه توسعه امن نرمافزار است که بیتوجهی به آن میتواند عواقب جبرانناپذیری برای هر سازمان و کسبوکار وابسته به نرمافزار و سیستمهای کامپیوتری در پی داشته باشد.
چرا به کدنویسی امن (Secure Coding) نیاز داریم؟
بخش بسیار زیادی از حملات صورتگرفته در سالهای اخیر که منجر به نشتهای اطلاعاتی یا آسیب به خود نرمافزار شدهاند ناشی از عدم تنظیمات صحیح امنیتی در سطح کدنویسی و رعایتنشدن اصول کدنویسی امن بوده است. کد ناامن در صنایع مهم (بهعنوانمثال، امور مالی، مراقبتهای بهداشتی، انرژی و حملونقل) میتواند منجر به خسارات مالی، دستکاری بازار و سرقت، حتی آسیب فیزیکی شود. از سوی دیگر برای شرکتهایی که سرویسی را به مصرفکنندگان یا شرکتها ارائه میکنند، مطمئناً اعتماد مشتری بسیار ارزشمند است و ازدستدادن این اعتماد میتواند بر سود نهایی آنها تأثیر بگذارد؛ بنابراین اطمینان از شیوههای کدنویسی ایمن باید اولویت اصلی این سازمانها باشد.
تکنیک های کد نویسی ایمن
وقتی صحبت از شیوههای کدنویسی ایمن و بهطورکلی امنیت به میان میآید، ساده نگهداشتن فرایند تاحدامکان (KISS) ضروری است. رویههای پیچیده میتوانند منجر به نتایج متناقض شوند یا بدتر از آن، ممکن است منجر به نادیدهگرفتهشدن برخی اصول و ملاحظات شوند.
در این مقاله و مقالههای آتی از سری مقالههای کدنویسی امن قصد داریم تا با زبانی ساده و کاربردی به بررسی رایجترین خطاهای کدنویسی که باعث بهوجودآمدن آسیبپذیری در نرمافزار میشوند و روشهای بهینه برای دوری از این خطاها بپردازیم.
باتوجهبه رویکرد ما که مبتنی بر پوشش حداکثری آسیبپذیریهای موجود در فضای امنیت است به بررسی آسیبپذیریهای مطرح شده در OWASP Top 10 میپردازیم که رایجترین خطرات امنیتی را شامل میشود. بنابراین نقطه شروع خوبی محسوب میشود.
اعتبار سنجی ورودیها (Input Validation)
یکی از اصول اساسی امنیت نرمافزار است. تأیید اینکه مقادیر ارائه شده به برنامه با نوع یا قالب مورد انتظار مطابقت دارند، تا حد زیادی سطح حمله را کاهش میدهد.
یکی از اشتباهات رایج در اعتبارسنجی ورودیها استفاده از فهرستهای بلاک برای اعتبارسنجی است. بهعنوانمثال برنامه کاراکترها یا سمبلهای شناخته شده که در حملات مرسوم مورداستفاده قرار میگیرند را بلاک میکند. ضعف این رویکرد این است که ممکن است برخی نمادها نادیده گرفته شوند.
کدهای زیر را در نظر بگیرید:
String updateServer = request.getParameter("updateServer");
if(updateServer.indexOf(";")==-1 && updateServer.indexOf("&")==-1){
String [] commandArgs = {
Util.isWindows() ? "cmd" : "/bin/sh",
"-c", "ping", updateServer
}
Process p = Runtime.getRuntime().exec(commandArgs);
{
در این مثال هرچند اعتبارسنجی انجام میشود؛ ولی همچنان کد نسبت به تزریق دستورات (command injection) آسیبپذیر است. (`rm -rf /`)
در مقابل کد زیر ورودیهای مجاز را مشخص میکند و تنها آنها را بهعنوان ورودی میپذیرد.
String updateServer = request.getParameter("updateServer");
if(ValidationUtils.isAlphanumericOrAllowed(updateServer,'-','_','.')){
String [] commandArgs = {
Util.isWindows() ? "cmd" : "/bin/sh",
"-c", "ping", updateServer
}
Process p = Runtime.getRuntime().exec(commandArgs);
{
به طور خلاصه میتوان از روشهای زیر استفاده کرد:
· اعتبارسنجی دادهها با استفاده از توالیهای خاص (مانند نوع داده، محدوده، طول ورودی در برابر کاراکترهای مجاز)
· بررسی بر اساس ورودیهای معتبر بهجای ورودیهای نامعتبر
· مطمئن شوید که مقادیر درخواستها/پاسخها همه کاراکترهای ASCII هستند