امن‌سازی Endpointهای API؛ از قرارداد دسترسی تا تست و Runbook

بیشتر Endpointهای ناامن با نبودن TLS یا یک ابزار عجیب شکست نمی‌خورند؛ شکست از جایی شروع می‌شود که تیم نمی‌تواند به چند پرسش ساده و دقیق جواب دهد: این درخواست دقیقاً چه عمل تجاری‌ای انجام می‌دهد؟ چه کسی روی کدام رکورد و کدام فیلد مجاز است؟ هزینه پردازش آن چقدر است؟ اگر درخواست دو بار رسید چه می‌شود؟ و هنگام سوءاستفاده چه شواهدی داریم؟ نصب API Gateway، انتخاب JWT یا افزودن WAF جای این قرارداد را نمی‌گیرد.

این راهنما برای امن‌سازی و تست پذیرش یک Endpoint نوشته شده است؛ از تعریف قرارداد دسترسی تا کنترل BOLA و BOPLA، سوءاستفاده از جریان تجاری، SSRF، بودجه منابع، Idempotency، پاسخ، لاگ و Runbook. برای طراحی برنامه امنیت در سطح کل سبد REST، GraphQL و Webhook، ابتدا راهنمای جامع امنیت API و OWASP را بخوانید. اینجا واحد کار کوچک‌تر و عملی‌تر است: یک Method و Path که باید پیش از انتشار، شواهد قبولی تولید کند.

امن‌سازی Endpoint API دقیقاً یعنی چه؟

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

OWASP API Security Top ۱۰ نسخه ۲۰۲۳ موضوع‌هایی مانند مجوزدهی شکسته در سطح شیء و ویژگی، مصرف نامحدود منابع، دسترسی نامحدود به جریان‌های حساس، SSRF، موجودی ناقص و اعتماد ناامن به API ثالث را برجسته می‌کند. این فهرست برای آگاهی و Threat modeling مفید است، اما خودش Specification یا Test plan کامل یک Endpoint نیست.

سؤالپاسخ ضعیفشاهد قابل‌قبول
چه کسی مجاز است؟کاربر لاگین‌شدهSubject، Tenant، Role/Scope، Assurance و Policy مشخص
به چه چیزی دسترسی دارد؟سفارش خودشقانون Object و Property با تست Alice/Bob/Admin
چه ورودی می‌پذیرد؟JSON معتبرSchema، Allowlist، سقف اندازه و خطای قراردادی
چقدر منابع مصرف می‌کند؟Rate limit داریمبودجه درخواست، هم‌زمانی، Query، فایل، Export و Downstream
اگر تکرار شد؟کلاینت نباید تکرار کندIdempotency key، دامنه، TTL، پاسخ Replay و تست Race
چطور رخداد را می‌بینیم؟همه Payload را لاگ می‌کنیمAudit event کمینه، Redaction، Correlation ID، Alert و Runbook

Intent و مرز این راهنما

کلیدواژه اصلی این صفحه «امن‌سازی API» و «امن‌سازی Endpoint» است. عبارت‌های مکمل شامل چک‌لیست امنیت API، تست امنیت Endpoint، BOLA و BOPLA، امنیت JWT، Rate limiting، Idempotency و API security testing هستند. هدف جست‌وجو عملی است: توسعه‌دهنده یا مالک فنی می‌خواهد قبل از Release بداند چه کنترل‌هایی را کجا پیاده و چگونه قبول یا رد کند.

این صفحه جای طراحی هویت سازمانی، معماری Zero Trust یا تست نفوذ مستقل را نمی‌گیرد. برای Policy و Enforcement سراسری به مدل Zero Trust برای وب‌اپلیکیشن و برای ارزیابی مستقل به راهنمای تست نفوذ وب‌اپلیکیشن مراجعه کنید. تمرکز اینجا Acceptance قابل‌تکرار در سطح Endpoint است.

قرارداد امنیتی Endpoint را قبل از کدنویسی بنویسید

یک قرارداد خوب به‌اندازه‌ای کوتاه است که در Pull Request دیده شود و به‌اندازه‌ای دقیق است که از آن تست بسازید. OpenAPI می‌تواند شکل Request و Response را مستند کند، اما قرارداد امنیتی باید معنا و اثر تجاری را هم اضافه کند. عبارت «Bearer token required» نمی‌گوید دارنده توکن روی کدام شیء، فیلد یا تغییر وضعیت مجاز است.

فیلد قراردادپرسش الزامینمونه برای POST /v1/orders
Owner و Versionچه تیمی پاسخ‌گوست و تا چه تاریخی پشتیبانی می‌شود؟Checkout / v1 / بازبینی فصلی
ConsumerBrowser، Mobile، Partner یا Service؟اپ موبایل و وب First-party
Business actionاثر واقعی درخواست چیست؟رزرو موجودی و ایجاد سفارش پرداخت‌نشده
Data classPII، مالی، Credential یا عمومی؟شماره تماس و آدرس؛ حساس تجاری
Authenticationنوع Credential و Assurance چیست؟Session/OAuth access token معتبر
AuthorizationFunction، Object، Property و State چه قواعدی دارند؟فقط سبد Tenant جاری؛ قیمت سمت Server
InputSchema، Allowlist و Normalization چیست؟شناسه آدرس، اقلام، کد تخفیف؛ بدون total
Resource budgetاندازه، تعداد، زمان و هم‌زمانی چقدر است؟حداکثر ۱۰۰ قلم، Body محدود، Timeout پایین‌دست
Replayتکرار و Race چگونه کنترل می‌شوند؟Idempotency-Key به ازای Subject و Operation
Responseکدام فیلدها و خطاها قابل‌نمایش‌اند؟DTO صریح؛ بدون Cost داخلی یا Rule محرمانه
Telemetryچه Event و Metric بدون افشای داده ثبت می‌شود؟Outcome، Latency، Authz decision، order_id هش‌شده
Failure policyدر خرابی Identity، DB یا PSP چه می‌شود؟Fail closed برای مجوز؛ وضعیت قابل‌بازیابی برای سفارش

نمونه قرارداد فشرده

Endpoint: POST /v1/orders
Actor: authenticated customer in current tenant
Input: address_id, items[{sku, quantity}], coupon_code?
Server-owned: unit_price, discount, inventory, payable_amount, status
Authorization: actor owns cart and address; SKU is sellable in tenant
Preconditions: cart_version matches; address active; coupon eligible
Budget: body/items/query/time/concurrency/downstream calls are bounded
Replay: Idempotency-Key scoped to actor + operation + normalized payload
Response: explicit OrderCreated DTO; private fields denied by default
Audit: actor, tenant, action, outcome, policy/version, correlation_id
Failure: no duplicate order; ambiguous payment moves to verification state

این متن برای پیاده‌سازی کافی نیست، اما اختلاف‌های پنهان میان Product، Backend، Security و QA را زود آشکار می‌کند. آن را کنار قرارداد Data و Integration نگه دارید؛ مقاله یکپارچه‌سازی سایت با API، Webhook و Data Contract مرزهای وابستگی و Runbook را در سطح معماری توضیح می‌دهد.

زنجیره تصمیم هر Request

کنترل‌ها را به‌صورت زنجیره ببینید، نه مجموعه‌ای از Pluginها. ترتیب دقیق با معماری فرق دارد، اما هر مرحله باید Owner، Failure mode و Test داشته باشد:

  1. ارتباط امن و هویت سرویس یا Origin بررسی شود.
  2. Method، Path، Version، Content-Type، Encoding و اندازه مجاز باشند.
  3. Credential استخراج و از نظر امضا، صادرکننده، مخاطب، زمان و Context اعتبارسنجی شود.
  4. Subject، Tenant و Assurance به Context قابل‌اعتماد تبدیل شوند.
  5. مجوز Function، Object، Property و Business state در Server اعمال شود.
  6. ورودی با Schema و Allowlist Parse و Normalize شود؛ داده اضافی رد یا نادیده‌سازیِ قراردادی شود.
  7. بودجه منابع، Abuse و وابستگی‌های خروجی پیش از کار پرهزینه کنترل شوند.
  8. Transaction، Idempotency، Concurrency و Side effect مدیریت شوند.
  9. Response از DTO صریح و مجوز فیلدی ساخته، Cache و Error کنترل شوند.
  10. رویداد کمینه و نتیجه تصمیم برای مشاهده‌پذیری ثبت شود.

Gateway می‌تواند مراحل مشترک مانند TLS termination، Route، اعتبار اولیه Token، سقف اندازه و Rate limit را متمرکز کند. اما Gateway معمولاً نمی‌داند کاربر «الف» مالک سفارش ۴۲ است یا مدیر فروش اجازه دیدن فیلد هزینه تأمین را دارد. مجوز شیء و ویژگی باید نزدیک منطق و داده اعمال شود.

احراز هویت: JWT یک ویژگی امنیتی خودکار نیست

API Key، Cookie session، OAuth access token، mTLS و Workload identity ابزارهایی با Threat model متفاوت‌اند. انتخاب باید از Consumer، چرخه عمر Credential، امکان Revocation، سطح Assurance و اثر سرقت آغاز شود. API Key به‌تنهایی برای دسترسی حساسِ کاربر نهایی معمولاً هویت و مجوز کافی نمی‌سازد؛ Session مرورگر نیز بدون کنترل CSRF و Cookie درست، صرفاً «لاگین» نیست.

اگر JWT استفاده می‌کنید، Decode شدن Token هیچ چیز را اثبات نمی‌کند. RFC ۸۷۲۵، Best Current Practices برای JWT بر Allowlist الگوریتم، اعتبارسنجی عملیات رمزنگاری، کلید مناسب، Issuer و Audience و جلوگیری از Token substitution تأکید دارد. حداقل قرارداد اعتبارسنجی باید این موارد را روشن کند:

  • الگوریتم‌های مجاز در تنظیم Server ثابت‌اند؛ Header ارسالی کاربر آن‌ها را انتخاب نمی‌کند.
  • Signature و زنجیره Key/JWK معتبرند و Rotation یا Key compromise مسیر عملیاتی دارد.
  • iss، aud، exp، nbf و Claimهای الزامی با Clock skew محدود بررسی می‌شوند.
  • ID Token به‌جای Access token و Token مربوط به API دیگر پذیرفته نمی‌شود.
  • kid، jku یا Claimهای URL برای Lookup کورکورانه استفاده نمی‌شوند.
  • Logout، Suspension، تغییر Role و رخداد سرقت با عمر کوتاه، Session state یا Revocation متناسب پوشش می‌یابند.

برای OAuth، RFC ۹۷۰۰؛ OAuth ۲.۰ Security Best Current Practice مرجع جاریِ انتخاب Flow و دفاع در برابر تهدیدهای شناخته‌شده است. نام استاندارد به‌تنهایی تضمین نمی‌کند Client، Redirect URI، PKCE، Token storage و Resource server درست پیکربندی شده‌اند.

MFA و Step-up را در نقطه ریسک به‌کار ببرید

ممکن است Session کاربر برای مشاهده پروفایل کافی باشد اما تغییر شماره، افزودن حساب تسویه، صدور کلید API یا Refund بزرگ به Step-up نیاز داشته باشد. Policy باید نوع عمل، تازگی احراز هویت، ریسک دستگاه و Recovery را مشخص کند. برای حساب‌های کنترل‌کننده سامانه، راهنمای MFA پنل مدیریت الگوی استقرار و بازیابی را پوشش می‌دهد.

مجوزدهی را به چهار لایه بشکنید

بسیاری از نقص‌های جدی وقتی رخ می‌دهند که تیم فقط Route-level role check دارد. مجوز مؤثر دست‌کم چهار تصمیم جداست:

لایهسؤالشکست نمونهتست منفی
Functionآیا Actor اصولاً این عمل را دارد؟کاربر عادی به Endpoint ادمین می‌رسدUser نقش عادی، Method و Route ادمین را صدا بزند
Objectآیا روی این رکورد مشخص مجاز است؟تعویض order_id، سفارش دیگری را نشان می‌دهدAlice شناسه Bob را درخواست کند
Propertyکدام فیلد را می‌تواند بخواند یا تغییر دهد؟Client مقدار role یا unit_price می‌فرستدفیلد Server-owned به Payload تزریق شود
Business stateاین Transition اکنون مجاز است؟سفارش ارسال‌شده Cancel یا Refund دوباره می‌شودعمل در State، زمان یا سقف نامعتبر تکرار شود

BOLA: شناسه قابل‌حدس مسئله اصلی نیست

Broken Object Level Authorization یعنی Server پس از دریافت شناسه، رابطه Actor با Object را درست بررسی نمی‌کند. UUID می‌تواند حدس‌زدن را سخت‌تر کند، اما مجوز نیست. Query باید در Scope قابل‌اعتماد ساخته شود؛ مثلاً سفارش با tenant_id و owner_id جاری بازیابی شود، نه اینکه ابتدا هر سفارش پیدا و سپس به شرطی شکننده تکیه شود.

BOPLA و Mass Assignment: ورودی و خروجی را صریح کنید

Bind کردن مستقیم JSON به Model راهی کوتاه برای تغییر فیلدهای role، status، balance یا approved_at است. DTO ورودی باید Allowlist داشته باشد و Mapping به Model صریح باشد. در خروجی نیز Serialization کل Entity ممکن است شماره داخلی، حاشیه سود، Flag تقلب یا داده Tenant دیگر را افشا کند. Response model مستقل و مجوز Property لازم است.

// الگوی مفهومی؛ نام‌ها وابسته به Framework هستند
const input = OrderInput.parse(request.body)       // allowlist + limits
const actor = requireIdentity(request)
const cart = await carts.findOwned(input.cartId, actor.tenantId, actor.id)
authorize(actor, 'order:create', cart)
const result = await createOrder(mapServerOwnedValues(input, cart))
return OrderCreatedResponse.from(result, actor)    // explicit fields

جریان تجاری حساس را جدا از Rate limit محافظت کنید

یک درخواست ممکن است از نظر Syntax و Authentication معتبر باشد اما در مقیاس، ترتیب یا نیت مخرب باشد. ارسال OTP، آزمون کد تخفیف، رزرو بلیت، ساخت حساب، استعلام قیمت، افزودن کارت هدیه، درخواست Refund و Export نمونه‌های Sensitive business flow هستند. مهاجم الزاماً Rate بسیار بالا ندارد؛ ممکن است آهسته، توزیع‌شده و با هزار حساب قانونی عمل کند.

جریانارزش مهاجمکنترل‌های ترکیبیGuardrail محصول
ارسال OTP پیامکیتحمیل هزینه، مزاحمت یا EnumerationDevice/Account/Number/IP/ASN velocity، Cooldown، Risk scoreRecovery و دسترس‌پذیری برای کاربر واقعی
Coupon checkکشف کد یا مصرف انبوهAttempt budget، Binding، Monitoring، Rule server-sideخطای غیرقابل Enumeration
رزرو موجودیاحتکار یا ایجاد کمبود مصنوعیHold TTL، Account/device quota، payment bindingRelease قطعی و وضعیت شفاف
Refundبرداشت یا تکرار بازپرداختState machine، Step-up، سقف، four-eyes، idempotencyزمان پاسخ و مسیر بررسی
Exportاستخراج تدریجی دادهScope، row/time budget، async job، approval، auditNotification و امکان لغو

Rate limit باید چندبعدی و متناسب با عمل باشد: Subject، Tenant، Credential، Device، مقصد، شماره تلفن، IP/Network، Action و پنجره زمانی. IP به‌تنهایی پشت NAT، اپراتور موبایل یا VPN می‌تواند هم کاربر واقعی را مسدود کند و هم حمله توزیع‌شده را از دست بدهد. CAPTCHA نیز یک تصمیم محصول و دسترس‌پذیری است، نه دیوار جادویی.

برای هر Endpoint بودجه منابع تعریف کنید

OWASP در API4:۲۰۲۳ از Unrestricted Resource Consumption می‌گوید؛ مسئله فقط تعداد درخواست نیست. یک درخواست کوچک می‌تواند Query سنگین، Fan-out زیاد، فایل فشرده انفجاری، Export میلیونی یا فراخوانی پرهزینه پیامک و سرویس ثالث بسازد.

منبعبودجه قابل‌اندازه‌گیریتست مرزی
HTTP bodyByte پس از Decompression و پیش از Parseکمی زیر/روی سقف، Chunked و فشرده
JSONعمق، تعداد Node، طول String/ArrayNested object و Array بزرگ
Paginationpage size، cursor validity، max scanlimit منفی/بزرگ و cursor قدیمی
DatabaseQuery count، rows scanned، timeoutFilter بدترین حالت و tenant بزرگ
GraphQLDepth، complexity، aliases، batchFragment چرخه‌ای و alias fan-out
فایلنوع واقعی، اندازه، Pixel/page، زمان پردازشPolyglot، archive، تصویر عظیم
هم‌زمانیPer actor/tenant/global in-flightBurst و Slow request
DownstreamCall count، timeout، retry budget، costکندی یا ۴۲۹ سرویس پیامک/PSP

سقف‌ها باید از ظرفیت و ریسک کسب‌وکار بیایند، نه عدد ثابت اینترنتی. رفتار عبور از سقف نیز بخشی از Contract است: رد سریع، Queue، پاسخ ۴۲۹ با راهنمای Retry، Job ناهمگام یا کاهش قابلیت. Retry بی‌حد می‌تواند خرابی پایین‌دست را به Retry storm تبدیل کند.

ورودی: Parse محدود، Schema صریح و معنا سمت Server

پیش از Parse، Content-Type و Encodingهای پشتیبانی‌شده را Allowlist کنید. Methodهای تعریف‌نشده باید رد شوند. Schema فقط نوع را نسنجد؛ طول، Range، Format، تعداد، رابطه فیلدها و Unknown property را هم قرارداد کند. Normalize باید یک بار و پیش از Validation/Authorization انجام شود تا دو لایه برداشت متفاوت نداشته باشند.

  • Query و Command پایگاه داده Parameterized باشد؛ Escape عمومی جای Context-specific encoding و Parameterization را نمی‌گیرد.
  • نام فایل، MIME اعلامی و Extension را قابل‌اعتماد فرض نکنید؛ نوع واقعی و مسیر ذخیره مستقل بررسی شوند.
  • قیمت، تخفیف، وضعیت، Tenant، Role و Owner از Client پذیرفته نشوند؛ Server آن‌ها را از Context و داده معتبر بسازد.
  • اعداد فارسی/عربی، ۰۹... و +98...، فاصله و نیم‌فاصله را طبق قرارداد Locale تبدیل کنید؛ چند Normalization متفاوت می‌تواند دورزدن یا Duplicate بسازد.
  • خطای Validation باید قابل‌عمل باشد، اما Stack trace، SQL، Secret یا تفاوتی که Enumeration بسازد افشا نکند.

Endpointهای URLمحور را برای SSRF طراحی کنید

Webhook tester، Import from URL، دریافت تصویر، PDF generator، Link preview و Callback validator می‌توانند Server را وادار کنند به مقصد انتخابی مهاجم درخواست بفرستد. Regex روی رشته URL یا Block کردن localhost کافی نیست؛ Redirect، DNS rebinding، IP notation، IPv6، Credential در URL و شبکه Metadata باید در Threat model باشند.

  1. اگر ممکن است مقصد را از شناسه Server-side انتخاب کنید، نه URL آزاد کاربر.
  2. Scheme، Host و Port را Parse و Canonicalize کنید؛ Allowlist مقصد بر Blocklist مقدم است.
  3. DNS را Resolve و هر IP خصوصی، Loopback، Link-local و شبکه داخلی ممنوع کنید؛ پس از Redirect دوباره بررسی کنید.
  4. Redirect خودکار، Cookie، Authorization header و Proxy محیط را پیش‌فرض خاموش کنید.
  5. Egress شبکه را محدود و سرویس Fetch را از Metadata و Control plane جدا کنید.
  6. اندازه پاسخ، زمان، تعداد Redirect و Content-Type را بودجه‌بندی کنید و Event ثبت کنید.

Idempotency و Concurrency: دوبار کلیک یک رخداد امنیتی هم هست

شبکه موبایل، Timeout، Retry کتابخانه، دوبار کلیک و Queue delivery می‌توانند یک درخواست را تکرار کنند. مهاجم نیز همین ابهام را برای سفارش، انتقال، شارژ، Coupon یا Refund آزمایش می‌کند. RFC 9110 Methodهای Safe و Idempotent را تعریف می‌کند؛ POST ذاتاً Idempotent نیست، اما کاربرد می‌تواند با قرارداد مشخص آن را برای تکرار امن کند.

قرارداد Idempotency-Key

  • کلید به Actor/Tenant، Operation و نسخه Payload Normalized Scope شود.
  • ثبت کلید و اثر تجاری Atomic باشد؛ Check-then-act ساده Race دارد.
  • Payload متفاوت با همان کلید Conflict صریح بدهد، نه نتیجه قبلیِ نامرتبط.
  • TTL از پنجره Retry و ریسک کسب‌وکار مشتق و رفتار پس از انقضا مستند شود.
  • پاسخ Replay از نظر Status و Body قراردادی باشد و Secret را دوباره افشا نکند.
  • Idempotency جای Lock، Optimistic concurrency یا State machine را نمی‌گیرد.

برای Updateهای رقابتی، Version/ETag و Precondition مانع Last-write-wins ناخواسته می‌شود. برای موجودی یا Balance، invariant باید داخل Transaction یا Primitive سازگارِ Data store اعمال شود. تست با دو Request هم‌زمان مهم‌تر از دو Request پشت‌سرهم است.

پاسخ، خطا و Cache را بخشی از مرز امنیت بدانید

GraphQL به Client امکان انتخاب Field می‌دهد، اما «ذاتاً» جلوی Excessive data exposure را نمی‌گیرد؛ Schema، Resolver authorization، Field-level policy و Complexity budget همچنان لازم‌اند. در REST نیز ORM Entity را مستقیماً Serialize نکنید. خروجی باید از DTO صریح ساخته شود و Default برای فیلد جدید «عدم نمایش» باشد.

برای خطا می‌توان از ساختار Problem Details در RFC ۹۴۵۷ الهام گرفت: نوع پایدار، عنوان قابل‌فهم، Status، شناسه رخداد و جزئیات امن. پیام عمومی برای Client و جزئیات تشخیصی Redacted در Telemetry جدا باشند. تفاوت خطا یا زمان پاسخ نباید وجود حساب، شماره، Coupon یا Object را ناخواسته آشکار کند.

موضوعقاعدهتست
Cacheداده خصوصی Cache عمومی نشود؛ Key/Vary شامل Context لازم باشدپاسخ Alice پس از درخواست Bob دیده نشود
GET حساسSecret و PII در URL/Query قرار نگیردAccess log، History و Referrer بررسی شود
خطاStack/SQL/Path/Token افشا نشودMalformed، timeout و dependency failure
DownloadAuthorization در لحظه دریافت و URL کوتاه‌عمرReplay، user swap و expiry
ContentMedia type، nosniff و filename امنHTML/SVG یا CRLF تزریقی

CORS و CSRF را با هم اشتباه نگیرید

CORS کنترل می‌کند کدام Origin در Browser اجازه خواندن پاسخ را دارد؛ سازوکار احراز هویت یا مجوز Server نیست و Client غیرمرورگری را متوقف نمی‌کند. Allow-origin باز همراه Credentials یا Reflection بی‌اعتبار Origin خطرناک است. Originهای لازم، Methodها و Headerها را محدود و پاسخ Cacheشونده را با Vary: Origin درست مدیریت کنید.

CSRF وقتی مهم است که Browser Credential را خودکار—مانند Cookie—همراه Request می‌فرستد. SameSite مناسب، CSRF token، Origin/Referer verification و منع State change روی GET را متناسب ترکیب کنید. ذخیره Token در JavaScript نیز مسئله XSS و سرقت Token را ایجاد می‌کند؛ هیچ انتخابی بدون Trade-off نیست.

TLS و Encryption لازم‌اند، اما کافی نیستند

HTTPS داده را در مسیر تعریف‌شده محافظت می‌کند، به شرط اعتبار Certificate، تنظیم درست Client/Proxy و نبود Downgrade یا Termination ناامن. این کنترل مانع کاربر معتبرِ بدون مجوز، SSRF، Mass assignment یا افشای داده در Response نمی‌شود. در ارتباط سرویس‌به‌سرویس، هویت Workload و Trust boundary را هم مشخص کنید؛ «شبکه داخلی» دلیل اعتماد نیست.

Encryption at rest اثر سرقت Disk یا Snapshot را کاهش می‌دهد، اما وقتی Application با همان Key داده را می‌خواند، مهاجم دارای دسترسی Application هم می‌تواند آن را بخواند. Key management، جداسازی دسترسی، Rotation، Backup و Audit تعیین می‌کنند Encryption چقدر مؤثر است. Secretها نباید در Repository، Image، URL، Log یا Client bundle باشند.

مرز API Gateway و WAF

Gateway برای Policyهای سراسری مانند Route inventory، TLS، اعتبار اولیه Token، Client quota، Request size و Telemetry نقطه خوبی است. بااین‌حال می‌تواند Dependency بحرانی، محل پیکربندی اشتباه یا هدف دورزدن باشد. Origin باید فقط از مسیرهای مجاز قابل‌دسترسی باشد و Policy میان Gateway و Application ناسازگار نشود.

WAF می‌تواند الگوهای شناخته‌شده، Bot و بخشی از Payloadهای مخرب را در لبه کاهش دهد؛ مالک مجوز شیء، invariant تراکنش یا Business abuse نیست. برای انتخاب و Test policy، راهنمای فایروال و WAF سایت را ببینید. معیار خوب فقط Block count نیست؛ False positive، Bypass، Latency و زمان واکنش هم مهم‌اند.

پاسخ API ثالث را ورودی غیرقابل‌اعتماد بدانید

API پرداخت، پیامک، نقشه، CRM یا هوش مصنوعی خارج از Trust boundary شماست. HTTPS و قرارداد تجاری، Schema یا محتوا را قابل‌اعتماد نمی‌کند. Timeout، Retry، Signature callback، Source authenticity، Schema validation، Response size، Redirect، HTML/Markdown خروجی و Dependency compromise باید کنترل شوند.

  • Callback درگاه را فقط از روی Redirect مرورگر موفق ندانید؛ نتیجه را Server-to-server تأیید و مبلغ، سفارش، وضعیت و یکتایی را تطبیق دهید.
  • Signature Webhook را روی Raw body و الگوریتم قراردادی بررسی کنید؛ Timestamp/Replay window و Secret rotation داشته باشید.
  • پاسخ Third-party را پیش از SQL، Template، Command، URL fetch یا Log کردن Validate و Contextually encode کنید.
  • Circuit breaker و Timeout را با Idempotency و Reconciliation بسازید تا «نامشخص» به Duplicate تبدیل نشود.

همه Request و Response را لاگ نکنید

لاگ کامل می‌تواند Access token، Cookie، رمز، OTP، شماره کارت، آدرس، فایل و داده سلامت را به مخزن ثانویه‌ای با دسترسی گسترده تبدیل کند. ابتدا Event schema را تعریف کنید و Data minimization را پیش‌فرض بگیرید. Debug logging زمان‌دار و محدود با Audit trail دائمی یکی نیست.

ثبت شودثبت نشود یا Redact شوددلیل
timestamp، endpoint_id/version، outcome، latencyBody کامل پیش‌فرضعملیات بدون Data lake حساس
subject/tenant pseudonymous، authn assuranceToken، Cookie، API keyTrace تصمیم بدون Credential leakage
policy_id/version و authz resultPII خام مگر ضرورت مستندتوضیح‌پذیری و کمینه‌سازی
correlation/request/idempotency referenceSecret، OTP، CVV، passwordReconciliation امن
resource-budget class و throttle reasonQuery string حساستشخیص Abuse بدون افشا

Retention، دسترسی، Integrity، Clock، منطقه زمانی و حذف باید مالک داشته باشند. در ایران، ثبت شماره موبایل کامل یا متن پیامک برای Debug می‌تواند بیش از نیاز داده تولید کند؛ شناسه پایدار کم‌ریسک، Masking و دسترسی محدود معمولاً مفیدتر است.

Observability امنیتی را به Outcome وصل کنید

افزایش ۴۰۱ لزوماً حمله نیست و کاهش آن نیز سلامت را ثابت نمی‌کند. Signalها را با Endpoint، Actor class، Tenant، Outcome و Baseline تفکیک کنید. داشبورد حداقلی می‌تواند نرخ ۲xx/۴xx/۵xx، P50/P95/P99، Rejectهای Authn/Authz، Resource limit، Idempotency replay/conflict، Dependency failure و Business outcome را نشان دهد.

Alert باید Owner، Threshold/Anomaly، پنجره، Severity و لینک Runbook داشته باشد. برای طراحی SLI، Trace و هشدار قابل‌عمل به راهنمای Observability و مانیتورینگ مراجعه کنید. Sampling نباید رخداد مالی یا تغییر مجوز را گم کند؛ در مقابل، Telemetry بیش‌ازحد هم هزینه و ریسک حریم خصوصی می‌سازد.

ماتریس تست پذیرش امنیت Endpoint

Happy path فقط ثابت می‌کند یک درخواست مجاز گاهی کار می‌کند. تست امنیت باید تغییر کوچک در Actor، Object، Property، State، زمان، اندازه، ترتیب و وابستگی را پوشش دهد. هر Test case ورودی، Precondition، Expected status/body/side effect، Audit event و Cleanup دارد.

خانواده تستنمونه‌هاقبولی
Authenticationبدون Token، منقضی، aud/iss غلط، alg نامجاز، key قدیمیرد یکنواخت؛ بدون Side effect یا Leak
AuthorizationAlice/Bob، Tenant swap، Role downgrade، Field injectionFunction/Object/Property/State دقیق اعمال شود
SchemaUnknown field، Type confusion، Unicode، عمق/طول مرزیParse محدود و Error قراردادی
ResourceBody/Array/Page/Query/File/Burst/Concurrencyبودجه در هر لایه و بدون Collapse پایین‌دست
Business abuseOTP/Coupon/Reserve/Refund/Export با Velocity متفاوتAbuse کم و Recovery کاربر واقعی حفظ شود
Replay/Raceکلید یکسان/متفاوت، Payload متفاوت، ۲۰ Request هم‌زمانیک اثر قطعی، Conflict درست، Reconciliation ممکن
SSRF/UploadPrivate IP، redirect، DNS change، polyglot، archiveEgress/Type/size/time محدود
Browser/CacheOrigin مخرب، CSRF، cache cross-userهیچ خواندن/نوشتن یا نشت میان کاربر رخ ندهد
Dependencytimeout، ۴۲۹، پاسخ malformed، callback تکراریRetry محدود، State معلوم/قابل‌تطبیق، بدون Duplicate
Telemetryهر Failure بالاEvent کافی بدون Secret/PII ناموجه

ماتریس Alice/Bob/Admin

Case  Actor   Object owner  Property        State      Expected
A1    Alice   Alice         public fields   paid       200
A2    Alice   Bob           public fields   paid       deny
A3    Admin   Bob           support fields  paid       policy-dependent
A4    Admin   Bob           secret fields   paid       deny by default
A5    Alice   Alice         unit_price      draft      ignore/reject; server-owned
A6    Alice   Alice         cancel          shipped    conflict/deny
A7    Alice   Alice         refund          refunded   idempotent result/no duplicate

تست‌ها باید علیه Policy واقعی و Data fixture چند Tenant اجرا شوند. Status code یک انتخاب قراردادی است؛ مهم‌تر این است که هیچ Side effect، تفاوت قابل‌سوءاستفاده یا Audit gap ایجاد نشود.

چه چیزی را در CI/CD خودکار کنیم؟

Contract test برای Method/Schema/Error، تست مجوز با Fixture، Dependency scanning، SAST، Secret scanning و تست‌های Race منتخب را در Pipeline قرار دهید. DAST و Fuzzing برای کلاس‌هایی از ورودی مفیدند، اما Context مالکیت و منطق Refund را از روی URL کشف نمی‌کنند. اسکن سبز باید یک شاهد در کنار Review و تست باشد، نه Gate یگانه.

NIST SSDF 1.1 توصیه‌های توسعه امن را در SDLC ادغام می‌کند؛ برای پیوند کنترل‌ها با Build، Artifact، Provenance و Rollback نیز راهنمای CI/CD امن را ببینید.

Gateشاهدقاعده شکست
ContractOpenAPI/Schema diff و compatibilityField/permission جدید بدون Review
Authorizationماتریس Actor/Object/Property/Stateهر دسترسی نامجاز یا Fixture ناقص
ResourceBoundary/load test کنترل‌شدهنبود سقف یا SLO breach شدید
Supply chainSCA/SBOM/Provenance و PolicyRisk خارج از SLA یا Artifact ناشناخته
RuntimeCanary metric، alert و rollback probeTelemetry/Runbook/rollback نامعتبر

Inventory، نسخه و حذف Endpoint

Endpoint فراموش‌شده همان‌قدر خطر دارد که Endpoint جدید. Routeهای Production را با Spec، Gateway، Code و Traffic تطبیق دهید. برای هر نسخه Owner، Consumer، Data class، Auth policy، تاریخ آخرین استفاده، Deprecation و Sunset ثبت کنید. نسخه قدیمی بدون Monitor و مهلت حذف، Shadow API می‌شود.

  • Spec با Runtime route مقایسه و اختلاف Alert شود.
  • Environmentهای Test، Admin، Debug و Management از اینترنت عمومی جدا یا هم‌سطح Production محافظت شوند.
  • نسخه منسوخ ابتدا Usage measurement و Consumer notification، سپس محدود و در نهایت حذف شود.
  • Secret و Credential مربوط به Consumer بازنشسته Rotate یا Revoke شود.
  • پس از حذف، Route و DNS/Proxy rule واقعاً ۴۰۴/۴۱۰ دهند و Backend دورزدنی باقی نماند.

ملاحظات عملی برای API در ایران

کنترل جهانی است، اما سناریوی قبولی باید شرایط واقعی مصرف‌کننده ایرانی را پوشش دهد. شبکه ناپایدار و تغییر IP می‌تواند Retry و Request تکراری را بیشتر کند؛ راه‌حل، حذف سقف یا اعتماد به IP نیست، بلکه Idempotency، Timeout روشن و UX وضعیت نامشخص است. تاریخ و پول نیز باید Contract صریح داشته باشند.

موضوعریسک رایجقرارداد پیشنهادی
موبایل۰۹، +۹۸، +۹۸ و رقم فارسی هویت تکراری می‌سازندCanonical form، نمایش Masked، Rate چندبعدی
OTP پیامکیهزینه، تأخیر، Enumeration و RetryCooldown/expiry/attempt budget، تحویل غیرقطعی، Recovery
ریال/تومانخطای ده‌برابری و دست‌کاری amountMinor unit/واحد صریح، amount سمت Server، نمایش شفاف
درگاهRedirect موفق کاذب، callback تکراری یا مبهمVerify سمت Server، تطبیق amount/order، state machine، reconciliation
تاریختفاوت شمسی/میلادی و Asia/Tehran/UTCTimestamp استاندارد در API، Locale در نمایش، timezone صریح
شبکه/VPNIP مشترک یا متغیر و False positiveRisk چندسیگنالی، Step-up و مسیر بازیابی
سرویس خارجیEligibility، تحریم، Billing یا قطع ناگهانیبررسی شرایط رسمی، جایگزین قانونی، Export و Failover تمرین‌شده

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

چهار Runbook حداقلی

۱. نشت Token یا API Key

Signal و Scope را تأیید کنید، Credential را Revoke/Rotate و مسیر انتشار را ببندید، Tokenهای مرتبط و Sessionها را متناسب منقضی کنید، دسترسی‌های انجام‌شده را با Audit کمینه بررسی و Consumer را از مسیر امن مطلع کنید. Rotate بدون رفع Source leak فقط حادثه را تکرار می‌کند.

۲. مشاهده BOLA یا BOPLA

Endpoint/Version و Data class را مشخص، دسترسی آسیب‌پذیر را با Feature flag یا Policy محدود، شواهد را بدون گسترش Exposure حفظ و Query/Authorization root cause را اصلاح کنید. سپس همه Endpointهای الگوی مشابه و Serializerهای مشترک را جست‌وجو، داده در معرض را Scope و Retest مستقل انجام دهید.

۳. Abuse جریان تجاری

به‌جای Block سراسری IP، Actor/Device/Target/Velocity و هزینه را بخش‌بندی کنید. Threshold یا Queue را موقت تنظیم، مسیر کاربر واقعی و Support را حفظ، Accountهای درگیر و وابستگی پیامک/پرداخت را کنترل و پس از رخداد Policy را با داده False positive بازتنظیم کنید.

۴. اختلال یا Compromise سرویس ثالث

فراخوانی را محدود یا Circuit را باز، Credential ثالث را Rotate، داده ورودی/خروجی و Side effectهای نامشخص را Reconcile، Alternate path قانونی را فعال و Consumer را با وضعیت دقیق آگاه کنید. پس از بازیابی، Backlog را با Idempotency پردازش و Retry storm نسازید.

برنامه ۳۰، ۶۰ و ۹۰روزه

بازهکارDefinition of Done
روز ۱ تا ۳۰Inventory، انتخاب ۱۰ Endpoint پرریسک، قرارداد و ماتریس مجوزOwner/Data class/Policy/Budget/Test برای ۱۰ مورد ثبت شده
روز ۳۱ تا ۶۰اصلاح Authz/DTO/Idempotency، تست منفی و TelemetryGateهای اصلی سبز و Dashboard/Alert با Runbook متصل
روز ۶۱ تا ۹۰تست نفوذ هدفمند، Game day، حذف نسخه قدیمی و تعمیم TemplateRetest بسته، رخداد تمرینی پاسخ داده و Coverage گزارش شده

ریسک را با تعداد کنترل‌ها نسنجید. معیارهای بهتر شامل درصد Endpointهای پرریسک با قرارداد و Owner، پوشش ماتریس مجوز، زمان بستن یافته تا Retest، نرخ Duplicate مالی، درصد Eventهای بدون Secret، زمان تشخیص و مهار و تعداد نسخه‌های بدون مصرف اما فعال‌اند.

چک‌لیست انتشار Endpoint

  • Method، Path، Version، Consumer، Owner، Data class و اثر تجاری ثبت شده‌اند.
  • Authentication نوع Credential، Issuer/Audience/Lifetime/Rotation/Revocation روشن دارد.
  • Function، Object، Property و Business-state authorization جداگانه تست شده‌اند.
  • Input DTO صریح است و فیلدهای Server-owned از Client پذیرفته نمی‌شوند.
  • Body، Parse، Query، File، Page، Concurrency و Downstream بودجه دارند.
  • Business abuse با Rate چندبعدی و Guardrail تجربه کاربر پوشش یافته است.
  • SSRF، Upload، Injection، CORS/CSRF، Cache و Error متناسب بررسی شده‌اند.
  • Idempotency، Race، Retry، Timeout و وضعیت نامشخص تست شده‌اند.
  • Response model فقط فیلدهای مجاز را می‌سازد و Default فیلد جدید Deny است.
  • Log و Trace بدون Token/Secret/PII ناموجه‌اند و Retention/Access دارند.
  • وابستگی ثالث Validate، Timeout و Reconciliation دارد.
  • تست منفی در CI و تست مستقل متناسب با ریسک برنامه‌ریزی شده است.
  • Dashboard، Alert، Runbook، Rollback و Owner کشیک قابل‌آزمایش‌اند.
  • Runtime route با Inventory/Spec منطبق و Deprecation تاریخ‌دار است.

پرسش‌های متداول

آیا API Gateway به‌تنهایی Endpoint را امن می‌کند؟

خیر. Gateway برای TLS، Route، بررسی اولیه Credential، Quota و Telemetry مشترک مفید است، اما معمولاً مالک رابطه کاربر با رکورد، مجوز فیلد و وضعیت کسب‌وکار نیست. این تصمیم‌ها باید در سرویس و نزدیک داده هم اعمال و تست شوند.

برای امنیت API، JWT بهتر است یا Session؟

پاسخ مطلق وجود ندارد. Consumer، Threat model، Revocation، Storage، CSRF/XSS، مقیاس و معماری تعیین‌کننده‌اند. JWT اگر Signature، الگوریتم، Issuer، Audience، زمان، Key rotation و نوع Token درست اعتبارسنجی نشوند، صرفاً یک رشته قابل‌حمل است.

تفاوت BOLA و BOPLA چیست؟

BOLA درباره مجوز روی یک Object مشخص است؛ مثلاً کاربر سفارش فرد دیگری را با تغییر شناسه می‌بیند. BOPLA درباره Fieldهاست؛ مثلاً کاربر فیلد نقش یا قیمت را تغییر می‌دهد یا پاسخ، فیلد محرمانه را افشا می‌کند. یک Endpoint می‌تواند هم‌زمان هر دو نقص را داشته باشد.

Rate limiting را بر اساس IP تنظیم کنیم؟

IP فقط یکی از سیگنال‌هاست. در شبکه موبایل، NAT و VPN ممکن است چند کاربر یک IP یا یک کاربر IPهای متعدد داشته باشند. Subject، Tenant، Credential، Device، Target، Action، Cost و Velocity را ترکیب کنید و مسیر بازیابی کاربر واقعی را بسنجید.

حداقل تست امنیتی پیش از انتشار Endpoint چیست؟

علاوه بر Happy path، Token نامعتبر، Alice/Bob/Tenant swap، فیلد اضافی، State نامجاز، ورودی مرزی، Request هم‌زمان و تکراری، Timeout وابستگی، Cache cross-user و Redaction لاگ را تست کنید. برای Endpoint مالی یا داده حساس، تست نفوذ مستقل و Game day رخداد هم متناسب است.

جمع‌بندی

امنیت Endpoint محصول نصب یک Gateway، WAF یا فرمت Token نیست. نقطه شروع یک قرارداد قابل‌تست است: چه Subjectی، روی کدام Object و Property، در چه State و با چه بودجه‌ای می‌تواند چه اثر تجاری‌ای ایجاد کند. سپس Authentication، Authorization، Schema، Abuse control، SSRF، Idempotency، Response، Telemetry و Runbook باید همان قرارداد را در Runtime حفظ کنند.

از ده Endpoint پرریسک شروع کنید. برای هرکدام ماتریس Alice/Bob/Admin و بودجه منابع بسازید، Race و Failure را واقعاً اجرا کنید و شواهد را به CI و Observability وصل کنید. هدف «صفر خطا» یا «اسکن سبز» نیست؛ هدف این است که تصمیم دسترسی درست، اثر جانبی محدود، شکست قابل‌بازیابی و رخداد قابل‌مهار باشد.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *