ساعت ۳ صبح یک آدرس IP یک صفحه ورود را درخواست کرد — به ظاهر بی‌خطر. اما بعداً همان منبع در چند میزبان و مسیر مختلف، پارامتری مثل ?debug=true را به URL اضافه کرد؛ این علامتِ جست‌وجوی یک مهاجم برای ارزیابی تکنولوژی‌ها و آماده‌سازی حمله است. ⚠️

خطاهای پیکربندی کوچک، رویدادهای فایروال که نادیده گرفته شده‌اند یا ناهنجاری‌های درخواست به‌تنهایی ساده به‌نظر می‌آیند. اما وقتی این سیگنال‌های کوچک همزمان شوند، می‌توانند به حادثه‌های امنیتی تبدیل شوند که به آن‌ها «toxic combinations» گفته می‌شود؛ جایی که مهاجم چند مشکل جزئی را کشف و روی هم انباشته می‌کند — مثلاً flag اشکال‌زدایی فعال (/ ?debug=true) یا مسیرهای بدون احراز هویت — تا به نفوذ یا استخراج داده‌ها برسد. Cloudflare ترافیک ورودی به استک شما را می‌بیند و بر همین اساس می‌تواند این ترکیب‌های سمی را در لحظه تشخیص دهد. در ادامه نشان می‌دهیم چگونه از داده‌های application security این سیگنال‌ها را بیرون می‌کشیم، انواع رایج ترکیب‌های سمی را توضیح می‌دهیم و می‌گوییم چطور می‌توانید از این اطلاعات برای پیدا کردن و رفع ضعف‌ها استفاده کنید. 😊

چطور «toxic combinations» را تعریف می‌کنیم؟

می‌توان «toxic combination» را به شکل‌های مختلفی تعریف کرد، ولی یک تعریف عملیاتی که روی داده‌های خودمان استفاده می‌کنیم این است: تقاطع ترافیک bots، مسیرهای حساس اپلیکیشن، ناهنجاری‌های درخواست و پیکربندی‌های نادرست. بیشتر حملات وب وقتی پیدا شد به‌سرعت خودکار می‌شوند؛ مهاجم exploit قابل‌اعتماد را اسکریپت کرده و با bot ادامه می‌دهد. با نگاه کردن به هم‌پوشانی این سیگنال‌ها (bot traffic، مسیرها، anomalies، misconfigs) می‌توانیم نشانه‌های یک نفوذ در حال شکل‌گیری را شناسایی کنیم. ابزارهای نقطه‌ای مثل Web Application Firewalls (WAF)، bot detection و API protection بیشتر روی ریسک یک درخواست منفرد تمرکز دارند؛ درحالی‌که تشخیص‌های Cloudflare برای «toxic combinations» دید را به سمت قصد کلی و همگرایی چند سیگنال برده تا حادثه‌ای که در حال شکل‌گیری است را پیدا کند.

چرا این تغییر دید مهم است؟ چون بسیاری از حوادث واقعی payload واضح یا signature مشخص ندارند و هیچ رویدادی به‌تنهایی فریاد «حمله» نمی‌زند. بنابراین ما برای ساختن چند نوع toxic combination از این زمینه‌ها استفاده می‌کنیم:
• Bot signals
• Application paths حساس مانند: admin، debug، metrics، search، payment flows
• Anomalies شامل: کدهای HTTP غیرمنتظره، پرش جغرافیایی (geo jumps), identity mismatch, high ID churn, نرخ-تجاوز به محدودیت (rate-limit evasion) با IP‌های توزیع‌شده که کار مشابهی انجام می‌دهند، spike در نرخ درخواست یا موفقیت
• Vulnerabilities یا misconfigurations مثل: نبود session cookie یا auth header، شناسه‌های قابل‌پیش‌بینی

مثال‌ها روی استک‌های محبوب

ما یک بازه ۲۴ ساعته از داده‌های Cloudflare را نگاه کردیم تا ببینیم این الگوها چقدر در استک‌های محبوب ظاهر می‌شوند. نتیجه نشان داد تقریباً ۱۱٪ از میزبان‌های تحلیل‌شده در برابر این ترکیب‌ها آسیب‌پذیر بودند که بخش بزرگی از آن ناشی از سایت‌های WordPress بود. اگر WordPress را حذف کنیم، فقط حدود ۰.۲۵٪ از میزبان‌ها نشانه‌هایی از toxic combinations قابل‌استفاده داشتند. هرچند نادر، اما این میزبان‌ها همان‌هایی هستند که احتمالاً قابل‌نفوذ می‌شوند. برای فهم بهتر، داده‌ها را به سه مرحله تقسیم کردیم:
• Estimated hosts probed: «تور گسترده» — میزبان‌های یونیکی که درخواست‌هایی به مسیرهای حساس (مثل /wp-admin) داشتند.
• Estimated hosts filtered by toxic combination: فهرست محدودتر از میزبان‌هایی که معیارهای ترکیب سمی را واقعاً داشتند.
• Estimated reachable hosts: میزبان‌هایی که به تلاش exploit پاسخ موفق (مثلاً 200 OK) دادند — این مرحله مثل «the smoking gun» است، اما باید بررسی reachability انجام شود چون یک 200 ساده ممکن است false positive باشد (مثلاً مسیرهای احراز هویت‌شده که بدون اعتبار واقعی 200 برمی‌گردانند یا redirectهایی که مسیر واقعی را پنهان می‌کنند). در بخش‌های بعدی منطق ترکیب‌ها و یافته‌ها را بازتر می‌کنیم. کوئری‌های تشخیصی لازم هستند اما بدون آزمون reachability کافی نیستند؛ بعضی موارد ممکن است مثبت کاذب باشند. در بعضی مواقع می‌توانید این کوئری‌ها را در Cloudflare Log Explorer روی لاگ‌های unsampled اجرا کنید. 📊

Probing of sensitive administrative endpoints across multiple application hosts

چی دیدیم؟

ابزارهای خودکار در حال اسکن صفحات ورود مدیریتی رایج بودند — مثل پنل‌های مدیریت WordPress (/wp-admin)، مدیریت دیتابیس‌ها و داشبوردهای سرور. نسخه تمپلیت‌شده کوئری قابل اجرا در Cloudflare Log Explorer به‌صورت زیر است:

SELECT
  clientRequestHTTPHost,
  COUNT(*) AS request_count
FROM
  http_requests 
WHERE
  timestamp >= '{{START_DATE}}'
  AND timestamp <= '{{END_DATE}}'
  AND edgeResponseStatus = 200
  AND clientRequestPath LIKE '{{PATH_PATTERN}}' //e.g. '%/wp-admin/%'
  AND NOT match( extract(clientRequestHTTPHost, '^[^:/]+'), '^\d{1,3}(\.\d{1,3}){3}(:\d+)?$') // comment this line for Cloudflare Log Explorer
  AND botScore < {{BOT_THRESHOLD}} // we used botScore < 30
GROUP BY
  clientRequestHTTPHost
ORDER BY
  request_count DESC;

چرا جدی است؟

پنل‌های مدیریتی در معرض عمومی می‌توانند هدف حملات brute force قرار بگیرند. در صورت موفقیت، مهاجم می‌تواند میزبان را به شبکه‌ای از بات‌ها اضافه کند و برای نفوذ به سایت‌های دیگر از آن استفاده کند. این ترکیب سمی می‌تواند منجر به:
• Exploit scanning: مشخص کردن نسخه نرم‌افزار (مثل Tomcat یا WordPress) و اجرای exploitهای شناخته‌شده (CVEها).
• User enumeration: بسیاری از پنل‌های مدیریت به‌طور ناخواسته نام‌کاربری‌های معتبر را لو می‌دهند که به مهاجم برای حملات بعدی کمک می‌کند.

چه شواهدی آن را پشتیبانی می‌کند؟

ترکیب سمی از automation بات‌ها و رابط‌های مدیریتی در معرض عمومی مانند: /wp-admin/, /admin/, /administrator/, /actuator/*, /_search/, /phpmyadmin/, /manager/html/, و /app/kibana/.
علائم و توضیحات:
• Bot activity — Bot Score < 30: نشانه‌هایی از اسکنرهای آسیب‌پذیری و بات‌ها
• Anomaly — Repeated Probing: ضربه‌های غیرعادی روی endpointهای admin
• Vulnerability — Publicly accessible endpoint: درخواست‌های موفق به مسیرهای مدیریتی

چطور این را کاهش دهم؟

چند اقدام عملی که در سطح SRE/DevOps قابل پیاده‌سازی هستند:
• Implement Zero Trust Access: اگر امکان‌پذیر است مسیرهای مدیریتی را پشت Zero Trust قرار دهید؛ فقط ترافیک تاییدشده باید دسترسی داشته باشد.
• اگر باید endpoint عمومی بماند، یک challenge platform مثل CAPTCHA یا challenge مبتنی بر رفتار برای افزایش هزینه حمله بگذارید تا بات‌ها کند یا متوقف شوند.
• IP allowlist: با WAF یا پیکربندی سرور فقط IPهای دفتر یا VPN شرکت را به مسیرهای مدیریتی اجازه دهید.
• Cloak admin paths: در صورت امکان آدرس‌های admin پیش‌فرض را تغییر دهید (مثلاً /wp-admin را به یک رشته غیرقابل‌حدس تغییر دهید). این کار یک لایه امنیت از طریق obscurity فراهم می‌کند اما کافی نیست.
• Geo-blocking: اگر مدیران شما فقط از کشورها/محدوده‌های جغرافیایی مشخصی کار می‌کنند، دسترسی به مسیرهای حساس را از مناطق دیگر ببندید.
• Enforce multi-factor authentication (MFA): هر نقطه ورود مدیریتی باید احراز هویت دومرحله‌ای داشته باشد؛ رمز عبور به‌تنهایی جلوی crawlers و credential stuffing را نمی‌گیرد.

Unauthenticated public API endpoints allowing mass data exposure via predictable identifiers

چی دیدیم؟

API endpointهایی پیدا کردیم که بدون نیاز به لاگین یا کلید در دسترس هر کسی روی اینترنت هستند (نگاه کنید به OWASP: API2:2023 – Broken Authentication). بدتر اینکه رکوردها با شناسه‌های ساده و قابل‌پیش‌بینی شناسایی می‌شوند (نگاه کنید به OWASP: API1:2023 – Broken Object Level Authorization)، یعنی هر کسی می‌تواند با تغییر یک عدد، دیتابیس شما را «شمارش» کند و به‌صورت گسترده داده‌ها را استخراج کند؛ حتی نیازی به بازدید از سایت شما هم نیست — فقط با درخواست‌های مستقیم به API.

نمونه کوئری بررسی روی بازهٔ مشخص به‌صورت زیر بود:

SELECT
  uniqExact(clientRequestHTTPHost) AS unique_host_count
FROM  http_requests
WHERE timestamp &gt;= '2026-02-13'
  AND timestamp &lt;= &#039;2026-02-14&#039;
  AND edgeResponseStatus = 200
  AND bmScore &lt; 30
  AND (
       match(extract(clientRequestQuery, &#039;(?i)(?:^|[&amp;?])uid=([^&amp;]+)&#039;),  &#039;^[0-9]{3,10}$&#039;)
    OR match(extract(clientRequestQuery, &#039;(?i)(?:^|[&amp;?])user=([^&amp;]+)&#039;), &#039;^[0-9]{3,10}$&#039;)
    OR length(extract(clientRequestQuery, &#039;(?i)(?:^|[&amp;?])uid=([^&amp;]+)&#039;))  BETWEEN 3 AND 8
    OR length(extract(clientRequestQuery, &#039;(?i)(?:^|[&amp;?])user=([^&amp;]+)&#039;)) BETWEEN 3 AND 8
  )

چرا جدی است؟

این یک آسیب‌پذیری «zero-exploit» است: مهاجم لازم نیست مهارت هک عمیقی داشته باشد، فقط کافی است یک عدد در لینک را تغییر دهد. پیامدها شامل می‌شود:
• Mass Data Exposure: استخراج گسترده دیتاست مشتریان شما.
• Secondary Attacks: داده‌های به‌دست‌آمده برای فیشینگ هدفمند یا takeover حساب‌ها استفاده می‌شود.
• Regulatory Risk: نقض وابسته به GDPR/CCPA و خطرات قانونی و جریمه‌ها.
• Fraud: رقبا یا بازیگران مخرب بینش تجاری و حجم مشتریان شما را به‌دست می‌آورند.

چه شواهدی آن را پشتیبانی می‌کند؟

این یک ترکیب سمی از نبود کنترل‌های امنیتی و اتوماسیون هدف‌گیری endpointهای خاص API است. علائم معمول:
• Bot activity — Bot Score < 30: ترافیک‌هایی با الگوهای اسکن اتوماتیک و حجم بالا از یک fingerprint که شناسه‌ها را iterate می‌کنند.
• Anomaly — High cardinality of IDs: یک بازدیدکننده در بازهٔ کوتاه صدها یا هزاران شناسهٔ متفاوت را درخواست می‌کند.
• Anomaly — Request pattern consistent with enumeration: الگوهایی که نشان می‌دهد پارامترهای user/uid به‌شکل ترتیبی یا شمارشی دست‌خورده‌اند.

نکاتی سریع برای کاهش این مشکل:

• احراز هویت و authorization مناسب برای endpointهای API را در اولویت قرار دهید؛ از tokenهای کوتاه‌مدت و scopes استفاده کنید.
• از شناسه‌های قابل‌پیش‌بینی اجتناب کنید: به‌جای اعداد ترتیبی از UUID یا شناسه‌های تصادفی استفاده کنید.
• Rate-limit دقیق و الگوریتم‌های detection برای patternهای enumeration پیاده کنید؛ توجه کنید به distributed rate-limit برای حملات توزیع‌شده.
• Logging و alerting روی high-cardinality access به resource ids فعال کنید تا سریعاً رفتارهای مشکوک را ببینید.
• در صورت امکان pagination امن و محدود کردن اندازه صفحات داده، scraping را هزینه‌بر کنید.

جمع‌بندی

برای تیم‌های DevOps/SRE: به‌جای تمرکز صرف روی یک درخواست در لحظه، روی همگرایی سیگنال‌ها کار کنید — bot indicators، مسیرهای حساس، ناهنجاری‌های رفتاری و misconfigurations — تا بتوانید toxic combinations را قبل از تبدیل‌شدن به حادثه واقعی شناسایی کنید. تشخیص زودهنگام و تست reachability همراه با اقدامات پیشگیرانه (Zero Trust، MFA، rate limits، شناسه‌های غیرقابل‌پیش‌بینی) اثر زیادی در کاهش سطح حمله خواهد داشت. اگر دوست دارید، می‌توانم کوئری‌ها را بر اساس لاگ‌های شما بازنویسی کنم یا playbook‌‌های تشخیصی و remediation مخصوص استک‌تان پیشنهاد دهم. 🚀