از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
بررسی آسیبپذیریهای کد پایتون با Bandit
سرفصلهای مطلب
معرفی
بهعنوان توسعهدهندگان، از ابتدای سفر به نوشتن تشویق میشویم کد تمیز. نوشتن و استفاده به همان اندازه مهم است، اما کمتر در مورد آن صحبت شده است کد امن.
در پروژههای پایتون، ما معمولاً ماژولها و بستههای شخص ثالث را نصب میکنیم تا از توسعه راهحلهایی که قبلاً وجود دارد اجتناب کنیم. با این حال، این روش رایج این است که چرا هکرها از وابستگی ها برای ایجاد خرابی در نرم افزار ما سوء استفاده می کنند و چرا باید بتوانیم تشخیص دهیم که چه زمانی مشکلی وجود دارد. به همین ترتیب ، ما از ابزاری مانند استفاده می کنیم راهزن، یک ابزار تجزیه و تحلیل امنیت منبع باز برای پروژه های پایتون.
در این راهنما – ما بررسی خواهیم کرد که چگونه خطوط ساده کد می توانند مخرب باشند و چگونه می توانیم از آنها استفاده کنیم راهزن برای کمک به ما در شناسایی آنها.
آسیب پذیری های امنیتی در پایتون
یک آسیب پذیری امنیتی در کد ما نقصی است که عوامل مخرب می توانند از آن برای سوء استفاده از سیستم ها و/یا داده های ما استفاده کنند. همانطور که در پایتون برنامهریزی میکنید، ممکن است استفاده آسیبپذیری از تماسهای کاربردی یا وارد کردن ماژولها وجود داشته باشد که ممکن است در صورت فراخوانی محلی ایمن باشد، اما در صورت استقرار بدون پیکربندی مناسب میتواند درهایی را برای کاربران مخرب باز کند تا سیستم را دستکاری کنند.
احتمالاً در فعالیت های روزانه کدنویسی خود با چندین مورد از این موارد برخورد کرده اید. برخی از حملات و سوء استفادههای رایجتر عمدتاً توسط چارچوبها و سیستمهای مدرنی که چنین حملاتی را پیشبینی میکنند، مقابله میکنند.
اینجا چندتایی هستند:
- OS Command Injection – مستقر روی فروتن
subprocess
ماژولی که برای اجرای آن استفاده می کنید command-line ابزارهای کاربردی و فراخوانی فرآیندهای مرتبط با سیستم عامل. قطعه زیر ازsubprocess
ماژول برای انجام جستجوی DNS و بازگرداندن خروجی:
import subprocess
domain = input("Enter the Domain: ")
output = subprocess.check_output(f"nslookup {domain}", shell=True, encoding='UTF-8')
print(output)
چه چیزی می تواند در اینجا اشتباه باشد؟
در یک سناریوی ایده آل، کاربر نهایی یک DNS ارائه می دهد و اسکریپت نتایج را برمی گرداند. nslookup
فرمان اما، اگر قرار بود دستوری مبتنی بر سیستم عامل مانند ls
همراه با DNS، خروجی زیر دریافت می شود – دستور نیز اجرا می شود:
$ python3 nslookup.py
Enter the Domain: rasanegar.com ; ls
Server: 218.248.112.65
Address: 218.248.112.65#53
Non-authoritative answer:
Name: rasanegar.com
Address: 172.67.136.166
Name: rasanegar.com
Address: 104.21.62.141
Name: rasanegar.com
Address: 2606:4700:3034::ac43:88a6
Name: rasanegar.com
Address: 2606:4700:3036::6815:3e8d
config.yml
nslookup.py
با اجازه دادن به کسی که بخشی از یک فرمان را منتقل کند – به او اجازه دسترسی به سطح سیستم عامل را می دهیم terminal.
تصور کنید که اگر بازیگر بدخواه دستوری مانند این را ارائه دهد، ممکن است اوضاع چقدر مخرب باشد cat /etc/passwd
که رمز عبور کاربران موجود را آشکار می کند. به همان سادگی که به نظر می رسد، subprocess
استفاده از ماژول می تواند بسیار خطرناک باشد.
- تزریق SQL – حملات SQL Injection این روزها نادر هستند، به لطف عملکردهای ORM که به طور گسترده مورد استفاده قرار می گیرند. اما اگر همچنان با استفاده از SQL خام هماهنگ هستید، باید از روش ساخت پرسوجوهای SQL و میزان امن بودن پارامترهای پرس و جو اعتبارسنجی و ارسال آن آگاه باشید.
قطعه زیر را در نظر بگیرید:
from django.db import connection
def find_user(username):
with connection.cursor() as cur:
cur.execute(f"""select username from USERS where name = '%s'""" % username)
output = cur.fetchone()
return output
فراخوانی تابع ساده است – مثلاً یک رشته را به عنوان آرگومان ارسال می کنید "Foobar"
و رشته در پرس و جوی SQL درج می شود و در نتیجه:
select username from USERS where name = 'Foobar'
با این حال، بسیار شبیه شماره قبلی – اگر کسی بخواهد یک را اضافه کند ;
شخصیت، آنها می توانند چندین دستور را زنجیره ای کنند. مثلا درج کردن '; DROP TABLE USERS; --
منجر به:
select username from USERS where name = ''; DROP TABLE USERS;
دستور اول درست قبل از اینکه پایگاه داده کل را رها کند اجرا می شود USERS
جدول. بله!
توجه داشته باشید که چگونه آخرین نقل قول با استفاده از دو خط تیره تفسیر شده است. پارامترهای پرس و جوی SQL، اگر به درستی بررسی نشوند، می توانند به کابوس تبدیل شوند. در اینجاست که ابزارهای امنیتی می توانند به شناسایی چنین خطوط کد ناخواسته و در عین حال مضر کمک کنند.
راهزن
Bandit
یک ابزار منبع باز نوشته شده در پایتون است که به شما کمک می کند کد پایتون خود را تجزیه و تحلیل کنید و مسائل امنیتی رایج در آن را پیدا کنید. میتواند کد پایتون شما را اسکن کند، آسیبپذیریها و اکسپلویتهایی مانند مواردی که در بخش قبل ذکر شد را شناسایی کند. Bandit می تواند به صورت محلی یا داخل محیط مجازی شما به راحتی از طریق نصب شود pip
:
$ pip install bandit
Bandit را می توان از دیدگاه های زیر استفاده کرد:
- DevSecOps: از جمله Bandit به عنوان بخشی از تمرینات یکپارچه سازی مداوم (CI).
- توسعه: Bandit می تواند به صورت محلی به عنوان بخشی از راه اندازی توسعه محلی استفاده شود، جایی که توسعه دهندگان می توانند قبل از اجرای کد، کنترل بر بهره برداری از عملکرد داشته باشند.
با استفاده از Bandit
Bandit را می توان به راحتی به عنوان بخشی از تست های CI ادغام کرد و بررسی آسیب پذیری های رایج را می توان قبل از ارسال کد به تولید انجام داد. به عنوان مثال، مهندسان DevSecOps میتوانند هر زمان که درخواست کششی مطرح میشود یا کدی در حال انجام است، برای امنیت بیشتر، Bandit را فراخوانی کنند. مستقر روی دستورالعمل های سازمان، import ماژول ها و فراخوانی تابع را می توان مجاز یا محدود کرد.
Bandit کنترل را برای کاربران فراهم می کند روی از کدام ماژول ها استفاده کنید و کدام ماژول ها را در لیست سیاه قرار دهید. این کنترل در داخل فایل پیکربندی تعریف شده است که می توان با استفاده از آن ایجاد کرد bandit-config-generator
ابزار خروجی تست های کد اجرا شده را می توان به صورت CSV، JSON و غیره صادر کرد.
فایل پیکربندی را می توان به صورت زیر تولید کرد:
$ bandit-config-generator -o config.yml
تولید شده config.yml
فایل حاوی چندین بخش مربوط به آزمایشهایی است که میتوانند مجاز یا باطل شوند، فراخوانیهای تابعی که میتوانند مجاز یا باطل شوند، در طول حداکثر طول کلیدهای رمزنگاری. کاربر ممکن است با تعیین این فایل پیکربندی از bandit استفاده کند یا تمام آزمایشات را به سادگی با عبور در فهرست پروژه انجام دهد:
$ bandit -r code/ -f csv -o out.csv
(main) INFO profile include tests: None
(main) INFO profile exclude tests: None
(main) INFO cli include tests: None
(main) INFO cli exclude tests: None
(main) INFO running روی Python 3.8.5
434 (0.. 50.. 100.. 150.. 200.. 250.. 300.. 350.. 400.. )
(csv) INFO CSV output written to file: out.csv
در این فراخوانی Bandit، دایرکتوری پروژه را با استفاده از -r
پرچم گذاری کنید و خروجی را به صورت CSV با استفاده از -o
پرچم. راهزن همه را آزمایش می کند python اسکریپت ها را در داخل این دایرکتوری پروژه قرار می دهد و خروجی را به صورت CSV برمی گرداند. خروجی بسیار دقیق است و در اینجا به نظر می رسد:
همانطور که در بخش قبل ذکر شد، subprocess
مدول import و shell=True
بحث تهدید امنیتی بالا هستند. اگر استفاده از این ماژول و آرگومان اجتنابناپذیر است، میتوان آنها را در لیست سفید در فایل پیکربندی قرار داد و با گنجاندن کدها، آن را مجبور به رد شدن از آزمایشها کرد. B602
(subprocess_popen_with_shell_equals_true) و B404
(import_subprocess) در “پرش”. ممکن است این کدها را در فایل پیکربندی تولید شده بیابید. تست هایی که در فایل موجود در skips
بخش به عنوان:
skips: (B602, B404)
اگر مجدداً با استفاده از فایل پیکربندی ایجاد شده، تستهای Bandit را اجرا کنید، یک فایل CSV خالی ایجاد میشود که نشان میدهد همه آزمایشها گذرانده شدهاند:
> bandit -c code/config.yml -r code/ -f csv -o out2.csv
(main) INFO profile include tests: None
(main) INFO profile exclude tests: B404,B602
(main) INFO cli include tests: None
(main) INFO cli exclude tests: None
(main) INFO using config: code/config.yml
(main) INFO running روی Python 3.8.5
434 (0.. 50.. 100.. 150.. 200.. 250.. 300.. 350.. 400.. )
(csv) INFO CSV output written to file: out2.csv
برای همکاری در داخل یک سازمان، این فایل پیکربندی راهزن باید در پروژه های تازه ایجاد شده تعبیه شود تا توسعه دهندگان بتوانند حتی به صورت محلی به آن دسترسی داشته باشند.
نتیجه
کد باید باشد تمیز و بی خطر. در این راهنمای کوتاه، نگاهی به آن انداختهایم راهزن، یک کتابخانه پایتون است که برای شناسایی مسائل امنیتی رایج با ماژول هایی که احتمالاً از قبل استفاده می کنید استفاده می شود.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-10 11:47:06