امنیت وب یکی از جنبه های مهم توسعه برنامه های کاربردی وب است process. به خصوص که داده های بیشتری ذخیره، مدیریت و به اشتراک گذاشته می شود.

به عنوان یک توسعه‌دهنده وب، اولویت‌بندی اقدامات امنیتی برای محافظت از کاربران و داده‌های شرکت در برابر تهدیدات احتمالی ضروری است.

در این مقاله، بهترین شیوه های امنیت وب را با ساختن یک برنامه وب امن با استفاده از جنگو، یک چارچوب وب قدرتمند پایتون، نشان خواهم داد. من هش رمز عبور، مدیریت جلسه امن، احراز هویت، مجوز، و سایر ملاحظات امنیتی کلیدی را با مثال‌های کد همراه پوشش خواهم داد.

قبل از ادامه این مقاله، به خاطر داشته باشید که این برای مبتدیان مطلق در نظر گرفته نشده است. برای استفاده حداکثری از این راهنما، باید درک خوبی از پایتون داشته باشید.

اگر نیاز به مسواک زدن دارید روی مهارت های اولیه برنامه نویسی شما در پایتون و جنگو قبل از ادامه، در اینجا چند منبع برای کمک به شما آورده شده است:

  • پایتون برای همه از دکتر چاک
  • جنگو برای همه ، همچنین از دکتر چاک

در پایان مقاله به کد دسترسی خواهید داشت.

ساختار پرونده خود را تنظیم کنید

بیایید بگوییم که ما می خواهیم پروژه خود را ذخیره کنیم روی دسکتاپ اولین کاری که انجام دهید این است که ساختار فایل خود را تنظیم کنید. بیایید با ایجاد یک شروع کنیم root دایرکتوری برای پروژه ما روی دسکتاپ (WebSec در این مورد).

mkdir WebSec
cd WebSec

یک محیط مجازی بسازید و آن را فعال کنید

در لینوکس (اوبونتو):

python3 -m venv my_env

Source my_env/bin/activate

و روی پنجره ها:

python -m venv my_env

my_env\Scripts\activate.bat

روش ایجاد پروژه Django

ابتدا، اگر قبلاً آن را ندارید، باید جنگو را با استفاده از دستور زیر نصب کنید:

python -m pip install Django

سپس می توانید از این دستور برای ایجاد پروژه استفاده کنید:

django-admin startproject web_sec_project .
یک پروژه جنگو ایجاد کنید. برای جلوگیری از تکرار پوشه، نقطه را فراموش نکنید.

و در نهایت از این دستور برای ایجاد اپلیکیشن استفاده کنید:

django-admin startapp web_sec_app
یک برنامه جنگو ایجاد کنید

ساختار فایل شما باید در پایان به شکل زیر باشد:

WebSec
    my_env/
    web_sec_app/
        __pycache__/
        migrations/
        templates/
        admin.py
        apps.py
        forms.py
        models.py
        tests.py
        urls.py
        views.py
    web_sec_project/
        __pycache__/
        __init__.py
        asgi.py
        settings.py
        urls.py
        wsgi.py
    db.sqlite3
    manage.py

سرور خود را اجرا کنید

در IDE شما terminal دستور زیر را اجرا کنید و تست کنید که آیا پروژه شما کار می کند یا خیر. اگر چنین است، شما خوب هستید که بروید.

python manage.py runserver

اطمینان حاصل کنید که برنامه خود را به پروژه خود اضافه کرده اید:

5KMFSFkkzM4T-YPujI0_9tm6FdnoTQRfJ8FbfVAZfChJfnkLRjvOSnyfq3PzIiLLWr-h-r5_mw9OOk55yJtXJ4OOjhu0wIwKiTiX5T__Htx4T cdn6b1BGgVSg
بررسی کنید که برنامه شما اضافه شده باشد

حالا بیایید ساخت و پیاده سازی امنیت وب را شروع کنیم.

هش کردن رمز عبور

اولین خط دفاعی هنگام اجرای امنیت وب، اطمینان از محافظت صحیح از رمزهای عبور کاربر است. و به جای ذخیره رمزهای عبور در متن ساده، ایده خوبی است که آنها را هش کنید. ما از هش رمزنگاری برای محافظت از اطلاعات حساس کاربر استفاده خواهیم کرد.

هش رمزنگاری، همچنین به عنوان توابع هش یا الگوریتم های هش شناخته می شود، یک مفهوم اساسی در رمزنگاری و امنیت رایانه است. این شامل گرفتن یک ورودی (یا “پیام”) و تبدیل آن به یک رشته کاراکتر با اندازه ثابت است که معمولاً دنباله ای از اعداد و حروف است. این خروجی “مقدار هش” یا “کد هش” نامیده می شود.

جنگو به طور پیش‌فرض، مکانیزم هش رمز عبور امن را با استفاده از PBKDF2 الگوریتم با a SHA-256 هش

جنگو از مکانیزم هش رمز عبور قوی و ایمن برای محافظت از رمزهای عبور کاربر استفاده می کند. این مکانیسم کمک می کند تا اطمینان حاصل شود که حتی اگر پایگاه داده به خطر بیفتد، مهاجمان نمی توانند به راحتی رمز عبور متن ساده کاربران را بازیابی کنند. مکانیسم هش رمز عبور جنگو شامل PBKDF2.

PBKDF2 یک تابع مشتق کلید رمزنگاری ساده است که در برابر حملات فرهنگ لغت و حملات جدول رنگین کمان مقاوم است. مبتنی است روی مشتق مکرر HMAC بارها با مقداری بالشتک. این تضمین می کند که حتی اگر پایگاه داده به خطر بیفتد، رمزهای عبور غیرقابل خواندن باقی می مانند.

برای نشان دادن این موضوع، ما قصد داریم یک کاربر جدید با رمز عبور هش شده ایجاد کنیم و کاربر را با رمز عبور هش شده خود در پایگاه داده ذخیره کنیم.

اول ما import را User از مدل کاربر سپس، ما import make_password. این کد برای انجام این کار است:

#web_sec_app/views.py

from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import User

# Create User views here.
def UserView(request):
    users = User.objects.all()
    password = 'password'
    hashed_password = make_password(password)
    return render(request, 'create_user.html', 
                {'users': users, 'hashed_password': hashed_password})
در دیدگاه ما.py ما یک تابع ایجاد می کنیم که یک کاربر جدید با رمز عبور هش شده ایجاد می کند و کاربر را با رمز عبور هش شده خود در پایگاه داده ذخیره می کند.

مدیریت جلسه ایمن

مدیریت جلسه کلید حفظ وضعیت کاربر در چندین درخواست است. جنگو دارای یک سیستم مدیریت جلسه داخلی است که داده های جلسه را ذخیره می کند روی سمت سرور ما مطمئن می شویم که داده های جلسه رمزگذاری شده است و شناسه جلسه برای جلوگیری از حملات ربودن جلسه ایمن است.

پیشنهاد می‌کنیم بخوانید:  دریافت تاریخ امروز در YYYY-MM-DD در Python

برای دستیابی به مدیریت امن جلسه، مطمئن خواهیم شد که یک کوکی جلسه امن داریم که به HTTPS نیاز دارد. ما هم قرار است پیشگیری کنیم JavaScript دسترسی به کوکی جلسه جلسه با بسته شدن مرورگر منقضی می شود.

SESSION_COOKIE_SECURE = True

این تنظیم به جنگو می‌گوید که کوکی جلسه را فقط از طریق اتصالات HTTPS ارسال کند. وقتی روی True، کوکی جلسه از طریق اتصالات HTTP رمزگذاری نشده ارسال نخواهد شد. این برای محافظت از داده‌های حساس جلسه، مانند توکن‌های احراز هویت کاربر، در برابر رهگیری توسط عوامل مخرب مهم است. روی شبکه های ناامن

SESSION_COOKIE_HTTPONLY = True 

تنظیمات SESSION_COOKIE_HTTPONLY به True یک لایه امنیتی اضافی اضافه می کند. وقتی این فعال باشد، کوکی جلسه با کد جاوا اسکریپت در حال اجرا قابل دسترسی نیست روی مرورگر مشتری این به کاهش انواع خاصی از حملات اسکریپت بین سایتی (XSS) کمک می کند، جایی که مهاجم سعی می کند داده های جلسه را با استفاده از اسکریپت های مخرب بدزدد.

SESSION_EXPIRE_AT_BROWSER_CLOSE = True

چه زمانی SESSION_EXPIRE_AT_BROWSER_CLOSE تنظیم شده است True، جلسه منقضی می شود و زمانی که کاربر مرورگر وب خود را ببندد حذف می شود. این مکانیسمی برای ایجاد جلسات کوتاه مدتی فراهم می کند که به طور خودکار پس از اتمام جلسه مرور کاربر به پایان می رسد. این برای سناریوهایی مفید است که می‌خواهید اطمینان حاصل کنید که کاربران هنگام بستن مرورگر خود از سیستم خارج می‌شوند و امنیت را برای رایانه‌های مشترک یا عمومی افزایش می‌دهد.

شما settings.py فایل باید حاوی موارد زیر باشد:

SESSION_COOKIE_SECURE = True 
SESSION_COOKIE_HTTPONLY = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True

احراز هویت و مجوز

رویه‌های احراز هویت و مجوز مناسب برای محدود کردن دسترسی به بخش‌های خاصی از برنامه وب مهم هستند.

در این بخش، روش پیاده سازی ورود و احراز هویت کاربر با استفاده از چارچوب احراز هویت جنگو را نشان خواهم داد. من همچنین بر اساس کنترل دسترسی را تعریف خواهم کرد روی نقش های کاربر برای اطمینان از اینکه فقط کاربران مجاز می توانند به نماها و ویژگی های خاص دسترسی داشته باشند.

@user_passes_test(lambda u: u.is_superuser)
def admin(request):
    return render(request, 'admin.html', {'username': request.user.username})

کد بالا برای محدود کردن دسترسی به نمای مدیریت استفاده می شود روی آیا کاربر یک ابرکاربر (ادمین) است یا خیر.

اگر کاربر یک ابرکاربر باشد، اجازه دسترسی به نما و الگو را دارد admin.html با نمایش نام کاربری آنها ارائه می شود. اگر کاربر ابرکاربر نباشد، به نمای غیرمجاز پیش‌فرض هدایت می‌شود، مگر اینکه مدیریت اضافی اجرا شود.

این تضمین می کند که فقط کاربران مجاز با امتیازات مدیریت می توانند به “admin.html” دسترسی داشته باشند. page.

حفاظت از اسکریپت بین سایتی (XSS).

Cross-Site Scripting (XSS) یک آسیب پذیری رایج است که به هکرها اجازه می دهد تا اسکریپت های مخرب را به صفحات وب که توسط سایر کاربران مشاهده می شوند تزریق کنند.

در این بخش، روش پیاده‌سازی هدرهای سیاست امنیتی محتوا (CSP) را برای جلوگیری از اجرای غیرمجاز اسکریپت و محافظت از برنامه‌مان در برابر حملات XSS را بررسی خواهیم کرد.

هدرهای CSP با ایجاد مجموعه‌ای از قوانین کار می‌کنند که تعیین می‌کنند کدام منابع محتوا مجاز و کدام مسدود هستند. این به طور قابل توجهی سطح حمله برای آسیب پذیری های XSS را کاهش می دهد و اجرای اسکریپت های غیرمجاز را برای مهاجمان سخت تر می کند. روی درخواست شما

بسیار مهم است که سیاست‌های CSP را به دقت پیکربندی کنید تا تعادلی بین امنیت و عملکرد ایجاد کنید، زیرا سیاست‌های بیش از حد محدودکننده به طور بالقوه می‌توانند عملکرد قانونی برنامه شما را از بین ببرند.

CSP_DEFAULT_SRC = ("'self'",)

حفاظت از جعل درخواست بین سایتی (CSRF).

حملات CSRF زمانی اتفاق می‌افتد که وب‌سایت‌های مخرب کاربران را فریب می‌دهند تا اقدامات غیرمجاز انجام دهند روی سایت های دیگری که در آن احراز هویت شده اند. جنگو با استفاده از توکن‌های CSRF محافظت داخلی در برابر حملات CSRF ارائه می‌کند.

این یکی از متداول ترین روش هایی است که برای جلوگیری از حملات CSRF با استفاده از توکن های CSRF استفاده می شود.

وقتی کاربر یک وب را بارگذاری می کند page که نیاز به تعامل کاربر دارد، سرور یک توکن منحصر به فرد تولید می کند و آن را در فرم یا داده های درخواست قرار می دهد. این نشانه معمولاً با جلسه کاربر مرتبط است. هنگامی که کاربر فرم را ارسال می کند یا اقدامی را آغاز می کند، سرور بررسی می کند که آیا نشانه ارسال شده با نماد مربوط به جلسه کاربر مطابقت دارد یا خیر. اگر مطابقت نداشته باشند، درخواست رد می شود، زیرا ممکن است تلاشی برای انجام یک حمله CSRF باشد.

من به شما نشان خواهم داد که چگونه این نشانه ها را در فرم ها قرار دهید تا از درخواست های غیرمجاز جلوگیری کنید.

<h4>Create Account</h4>
<form action="{% url 'create_user' %}" method="post">
   {% csrf_token %}
   <input 
      type="text" 
      id="userName" 
      name="username"
      class="form-control input-sm chat-input" 
      placeholder="username" 
    />
</form>

پیشگیری از تزریق SQL

تزریق SQL یک آسیب پذیری جدی است که زمانی رخ می دهد که مهاجمان ورودی های کاربر را برای اجرای کوئری های SQL مخرب دستکاری می کنند. روی پایگاه داده. من نشان خواهم داد که چگونه ORM جنگو (نقشه‌برداری شی-رابطه‌ای) به طور خودکار ورودی‌های کاربر را پاکسازی می‌کند و در برابر حملات تزریق SQL محافظت می‌کند.

پیشنهاد می‌کنیم بخوانید:  روش اعمال ریاضی با پایتون - تحلیل عددی توضیح داده شده است

توجه به این نکته مهم است که اگرچه ORM جنگو در برابر اکثر حملات تزریق SQL دفاع قوی ارائه می دهد، توسعه دهندگان همچنان باید از بهترین شیوه های امنیتی مانند اعتبار سنجی ورودی و بررسی های مجوز استفاده کنند تا امنیت کلی برنامه های وب خود را تضمین کنند.

همچنین ایده خوبی است که جنگو و وابستگی های آن را به طور مکرر به روز کنید تا از هر گونه به روز رسانی امنیتی یا سایر پیشرفت هایی که ممکن است در آینده منتشر شود، استفاده کنید.

def search(request):
    query = request.GET.get('q')
    if query is not None:
        results = Search.objects.filter(Q(name__icontains=query) | Q(description__icontains=query))
    else:
        results = []
    return render(request, 'search.html', {'results': results})

کد بالا یک تابع نمای جنگو را تعریف می کند که با استخراج یک پرس و جو از درخواست، عملکرد جستجو را مدیریت می کند. GET پارامترها، با استفاده از آن کوئری برای انجام جستجو در مدل جستجو با استفاده از روش فیلتر جنگو ORM، و سپس ارائه یک الگو با نتایج جستجو.

جستجو بر اساس انجام می شود روی ‘نام“و”شرح‘ زمینه های مدل، و نتایج به حروف بزرگ و کوچک مطابقت جزئی است.

با تکیه روی ORM جنگو و ویژگی‌های داخلی آن، شما از سطح بالاتری از انتزاع استفاده می‌کنید که ذاتاً به جلوگیری از آسیب‌پذیری‌های رایج تزریق SQL کمک می‌کند.

ساختار و الگوهای استفاده این کد با بهترین شیوه ها برای نوشتن پرس و جوهای ایمن در جنگو هماهنگ است و آن را کمتر در معرض حملات تزریق SQL قرار می دهد. اما همچنان مهم است که اطمینان حاصل شود که بقیه کدهای شما از بهترین شیوه های امنیتی پیروی می کنند و نسخه جنگو و وابستگی های خود را به روز نگه می دارید تا از آخرین وصله های امنیتی بهره مند شوید.

امنیت آپلود فایل

مدیریت آپلود فایل نیاز به توجه ویژه ای دارد تا مهاجمان از آپلود فایل های مخرب جلوگیری کنند. خواهیم دید که چگونه آپلود فایل ها را برای اطمینان از امنیت برنامه وب خود تأیید و محدود کنیم.

def upload_file(request):
    if request.method == 'POST':
        uploaded_file = request.FILES.get('file')
        if uploaded_file:
            if uploaded_file.content_type in ALLOWED_FILE_EXTENSIONS:
                try:
                    with open('uploads/' + uploaded_file.name, 'wb+') as destination:
                        for chunk in uploaded_file.chunks():
                            destination.write(chunk)
                    return render(request, 'success.html')
                except ValidationError as e:
                    error_message = str(e)
                    return render(request, 'fileUpload.html', {'error_message': error_message})
            else:
                error_message = "Invalid file type."
                return render(request, 'fileUpload.html', {'error_message': error_message})
        else:
            error_message = "No file selected."
            return render(request, 'fileUpload.html', {'error_message': error_message})
    else:
        return render(request, 'fileUpload.html')

قطعه کد بالا تابعی را به نام تعریف می کند upload_file این تابع یک شی درخواست را به عنوان آرگومان خود می گیرد و بارگذاری فایل را مدیریت می کند.

تابع ابتدا بررسی می کند که آیا روش درخواست وجود دارد یا خیر POST. اگر اینطور باشد، تابع فایلی را که کاربر با استفاده از آن آپلود می کند دریافت می کند request.FILES.get('file') روش.

اگر فایل خالی نباشد، تابع بررسی می کند که آیا پسوند فایل در فایل موجود است یا خیر ALLOWED_FILE_EXTENSIONS فهرست این لیست شامل انواع فایل هایی است که مجاز به آپلود هستند. اگر پسوند فایل در لیست نباشد، تابع یک پیغام خطا نمایش می دهد.

اگر پسوند فایل در لیست باشد، تابع سعی می کند فایل را در دایرکتوری به نام ذخیره کند uploads. تابع از with open() عبارت برای باز کردن فایل در حالت نوشتن باینری. سپس فایل با استفاده از for chunk in file.chunks() حلقه

اگر فایل با موفقیت ذخیره شود، این تابع کاربر را به سمت موفقیت هدایت می کند page. در غیر این صورت یک پیغام خطا نمایش داده می شود.

این ALLOWED_FILE_EXTENSIONS لیست یک اقدام امنیتی است که کاربران را از آپلود فایل های مخرب مانند فایل های اجرایی یا اسکریپت ها باز می دارد. حداکثر محدودیت اندازه فایل یکی دیگر از اقدامات امنیتی است که کاربران را از آپلود فایل های بزرگ که می تواند باعث حمله انکار سرویس شود جلوگیری می کند. ذخیره فایل آپلود شده در دایرکتوری جداگانه فایل را از بقیه برنامه جدا می کند و دسترسی مهاجمان به آن را دشوارتر می کند.

بسته بندی

ساخت یک برنامه وب امن یک امر مستمر است process که نیاز به هوشیاری و اجرای بهترین شیوه ها دارد.

در این مقاله، هنگام ساخت یک برنامه وب با استفاده از جنگو، اقدامات امنیتی مختلف وب را با نمونه‌های کد نشان دادم.

با پیاده سازی هش رمز عبور، مدیریت جلسه ایمن، احراز هویت، مجوز، و محافظت در برابر آسیب پذیری های رایج وب مانند XSS و CSRF، گام های مهمی در جهت ایجاد یک برنامه وب قوی و ایمن برداشته ام.

اما امنیت وب یک زمینه گسترده و همیشه در حال تحول است و برای اطمینان از ایمن ماندن برنامه وب شما در برابر تهدیدات احتمالی، به روز ماندن با آخرین روندها و شیوه های امنیتی بسیار مهم است. همیشه تست های امنیتی کامل را انجام دهید و به طور منظم برنامه و کتابخانه های خود را به روز کنید تا دفاعی قوی در برابر حملات احتمالی داشته باشید.

با اتخاذ تدابیر امنیتی مناسب، می توانید با اطمینان تجربه وب ایمن و ایمن را برای کاربران خود فراهم کنید.

در اینجا می توانید به کد دسترسی داشته باشید. با تشکر برای خواندن!