Application Security

تسلط بر CORS: راهنمای نهایی پیکربندی برای APIهای وب امن

در اکوسیستم مدرن میکروسرویس‌ها و برنامه‌های تک‌صفحه‌ای (SPAs)، اشتراک‌گذاری منابع بین مبدأ (CORS) به یکی از پرتکرارترین و در عین حال بدفهم‌ترین اما حیاتی‌ترین اجزای امنیت وب تبدیل شده است. اگر هرگز با پیام خطای گیج‌کننده‌ای در کنسول مرورگر خود مواجه شده‌اید که می‌گوید "دسترسی به fetch در... از مبدأ... توسط سیاست CORS مسدود شده است"، شما تنها نیستید. این راهنما هدف دارد تا CORS را شفاف‌سازی کند، مکانیسم‌های امنیتی زیربنایی را توضیح دهد و استراتژی‌های پیکربندی قوی را برای توسعه‌دهندگان ارائه دهد.

درک سیاست مبدأ یکسان

برای درک دلیل وجود CORS، باید ابتدا به سیاست مبدأ یکسان (SOP) نگاه کنیم. مرورگرها SOP را برای جداسازی اسناد بالقوه مخرب اعمال می‌کنند. دو مبدأ در صورتی یکسان در نظر گرفته می‌شوند که پروتکل، میزبان (دامنه) و پورت یکسان باشند. SOP از یک اسکریپت بارگذاری شده از https://app.example.com جلوگیری می‌کند تا داده‌ها را از https://api.example.com بخواند، مگر اینکه صراحتاً مجاز شود.

CORS به خودی خود یک ویژگی امنیتی نیست؛ بلکه مکانیسمی است که به وب‌سرورها اجازه می‌دهد SOP را تعدیل کنند. این مکانیسم راهی کنترل‌شده برای سرورها فراهم می‌کند تا درخواست‌های خاص بین مبدأ را مجاز کند و اطمینان حاصل کند که فقط مشتریان مورد اعتماد می‌توانند به داده‌های حساس دسترسی داشته باشند.

آناتومی یک درخواست CORS

هنگامی که یک مرورگر یک درخواست بین مبدأ انجام می‌دهد، به عنوان یک نگهبان عمل می‌کند. آن هدرهای پاسخ را از سرور بررسی می‌کند تا تعیین کند آیا باید درخواست مجاز شود یا خیر. دو نوع درخواست وجود دارد: ساده و پیش‌پرتاب (preflight).

درخواست‌های ساده نیاز به هیچ ارتباط قبلی ندارند. این‌ها درخواست‌های GET یا POST با انواع محتوای استاندارد (مانند application/x-www-form-urlencoded یا multipart/form-data) هستند. مرورگر درخواست را با یک هدر Origin ارسال می‌کند که نشان می‌دهد درخواست از کجا آمده است.

درخواست‌های پیش‌پرتاب زمانی رخ می‌دهند که روش درخواست DELETE، PUT یا PATCH باشد، یا زمانی که از هدرهای سفارشی (مانند X-Custom-Header) یا انواع محتوای غیراستاندارد استفاده شود. در این موارد، مرورگر ابتدا یک درخواست OPTIONS ارسال می‌کند تا از سرور بپرسد: "آیا اشکالی دارد اگر این درخواست اصلی را ارسال کنم؟" تنها در صورتی که سرور با هدرهای مجاز و روش‌های مجاز خاص پاسخ دهد، مرورگر به انجام درخواست اصلی ادامه می‌دهد.

هدرهای کلیدی CORS توضیح داده شده

پیکربندی بر تنظیم صحیح هدرهای HTTP استوار است. در اینجا مهم‌ترین آن‌ها آورده شده است:

  • Access-Control-Allow-Origin: مشخص می‌کند کدام مبدأها مجاز هستند. استفاده از * تمام مبدأها را مجاز می‌کند، اما این کار برای APIهای احراز هویت شده اغلب توصیه نمی‌شود.
  • Access-Control-Allow-Methods: روش‌های HTTP مجاز را فهرست می‌کند (مثلاً GET، POST، OPTIONS).
  • Access-Control-Allow-Headers: مشخص می‌کند کدام هدرها می‌توانند در درخواست اصلی استفاده شوند.
  • Access-Control-Allow-Credentials: اگر روی true تنظیم شود، اجازه ارسال کوکی‌ها و اطلاعات احراز هویت همراه با درخواست را می‌دهد.

مثال‌های پیکربندی عملی

در زیر مثال‌هایی از نحوه پیکربندی CORS در فریم‌ورک‌های بک‌اند محبوب آورده شده است. به یاد داشته باشید، هدف این است که تا حد امکان محدودکننده باشید و فقط موارد ضروری را مجاز کنید.

Node.js با Express

استفاده از میان‌افزار cors رویکرد استاندارد است. برای APIهای تولید، از استفاده از wildcard * خودداری کنید اگر نیاز به پشتیبانی از اعتبارنامه‌ها دارید.

const cors = require('cors');
const express = require('express');
const app = express();

// اجازه فقط به مبدأهای خاص
const corsOptions = {
  origin: ['https://frontend.example.com', 'http://localhost:3000'],
  optionsSuccessStatus: 200, // برخی مرورگرهای قدیمی با 204 مشکل دارند
  credentials: true // اجازه ارسال کوکی‌ها
};

app.use(cors(corsOptions));

Python با Flask

افزونه flask-cors این فرآیند را به طور قابل توجهی ساده می‌کند.

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
# محدود کردن به دامنه خاص
CORS(app, origins=["https://frontend.example.com"])

@app.route('/data')
def get_data():
    return {'message': 'Secured data'}

اشتباهات رایج و بهترین شیوه‌ها

یکی از رایج‌ترین اشتباهات، فعال کردن Access-Control-Allow-Credentials: true همزمان با تنظیم Access-Control-Allow-Origin: * است. این ترکیب طبق مشخصات CORS نامعتبر است. وقتی اعتبارنامه‌ها در میان هستند، باید مبدأ دقیق را مشخص کنید.

یک دام دیگر، مدیریت نادرست درخواست‌های پیش‌پرتاب است. اطمینان حاصل کنید که سرور شما برای درخواست‌های OPTIONS وضعیت 204 No Content یا 200 OK را برمی‌گرداند. اگر پیش‌پرتاب شکست بخورد، درخواست اصلی هرگز ارسال نخواهد شد که منجر به خطاهای گیج‌کننده می‌شود.

در نهایت، همیشه وضعیت امنیتی خود را در نظر بگیرید. پیکربندی‌های CORS خود را به طور منظم حسابرسی کنید. اگر سرویسی دارید که به دسترسی بین مبدأ نیاز ندارد، CORS را به طور کامل غیرفعال کنید یا آن را فقط به localhost محدود کنید. پیاده‌سازی یک سیاست امنیت محتوا (CSP) می‌تواند لایه دفاعی اضافی در برابر برخی انواع حملات نیز فراهم کند.

نتیجه‌گیری

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

Share: