Kodokon kodokon.com

تأمين واجهة برمجة تطبيقات في بيئة الإنتاج

قوِّ واجهة برمجة Node في بيئة الإنتاج: CORS صحيح، وتحديد المعدّل، وترويسات الأمان، ودفاعات ضد أبرز مخاطر OWASP لواجهات البرمجة.

11 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

تُصدِر OWASP قائمة بأبرز 10 مخاطر مخصّصة لواجهات البرمجة. والمخاطر الثلاثة المهيمنة هي: BOLA (كسر التخويل على مستوى الكائن - الوصول إلى كائن مستخدم آخر بتغيير معرّف)، وكسر المصادقة (Broken Authentication) (رموز مُتحقَّق منها بشكل سيّئ، وأسرار ضعيفة)، والاستهلاك غير المقيَّد للموارد (Unrestricted Resource Consumption) (لا حدّ على المعدّل أو الحجم أو الوقت). لاحظ أن أيًّا من الثلاثة لا يُحَل بتثبيت مكتبة: فهي خصائص تصميمك. لنبدأ بالآليات الشاملة: CORS، وتحديد المعدّل، والترويسات.

JAVASCRIPT
import { createServer } from "node:http";

const allowed = new Set(["https://app.example.com"]);

const server = createServer((req, res) => {
  const origin = req.headers.origin;
  if (origin && allowed.has(origin)) {
    res.setHeader(
      "Access-Control-Allow-Origin",
      origin,
    );
    res.setHeader("Vary", "Origin");
  }
  if (req.method === "OPTIONS") {
    res.setHeader(
      "Access-Control-Allow-Methods",
      "GET,POST,PUT,DELETE",
    );
    res.setHeader(
      "Access-Control-Allow-Headers",
      "content-type,authorization",
    );
    res.setHeader("Access-Control-Max-Age", "86400");
    res.writeHead(204).end();
    return;
  }
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify({ ok: true }));
});

server.listen(3000);
CORS يدويًا: قائمة السماح والطلب التمهيدي (preflight).

افهم بوضوح ما ليس عليه CORS: فهو ليس حمايةً للخادم. إذ يتجاهل curl أو خادمٌ خلفيٌّ تابعٌ لطرف ثالث هذه الترويسات تمامًا؛ والمتصفّح وحده هو من يفرضها، لحماية مستخدميه. وثمة ثلاث قواعد للخبراء: أرجِع المصدر الدقيق من قائمة سماح (لا تُعِد أبدًا صدى ترويسة Origin بشكل أعمى)، وأضِف Vary: Origin كي لا تُفسِد الذاكرات المؤقّتة الوسيطة، واعلم أن المتصفّحات ترفض الرمز البديل * بمجرد أن يحمل الطلب ملفات تعريف ارتباط (credentials).

JAVASCRIPT
const WINDOW_MS = 60_000;
const LIMIT = 100;
const hits = new Map();

function check(ip) {
  const now = Date.now();
  const entry = hits.get(ip);
  if (!entry || now - entry.start >= WINDOW_MS) {
    hits.set(ip, { start: now, count: 1 });
    return { ok: true, remaining: LIMIT - 1 };
  }
  entry.count += 1;
  const remaining = Math.max(LIMIT - entry.count, 0);
  return { ok: entry.count <= LIMIT, remaining };
}

console.log(check("203.0.113.7"));
نافذة ثابتة في الذاكرة: أرجِع 429 إذا كانت ok تساوي false.

تُكلّف ترويسات الأمان بضعة أسطر وتحجب فئات كاملة من الهجمات: فـ HSTS تفرض HTTPS للزيارات المستقبلية، وX-Content-Type-Options: nosniff تمنع المتصفّح من تخمين نوع MIME، وسياسة CSP المُقيِّدة (default-src 'none') تُبطِل استغلال استجابة واجهة برمجة عُرِضت خطأً في متصفّح. واحذف أيضًا أيّ ترويسة تكشف حزمتك التقنية: فـ Express تضيف X-Powered-By افتراضيًا - عطّلها بـ app.disable('x-powered-by').

JAVASCRIPT
function setSecurityHeaders(res) {
  res.setHeader(
    "Strict-Transport-Security",
    "max-age=63072000; includeSubDomains",
  );
  res.setHeader("X-Content-Type-Options", "nosniff");
  res.setHeader(
    "Content-Security-Policy",
    "default-src 'none'; frame-ancestors 'none'",
  );
  res.setHeader("Cache-Control", "no-store");
}

export { setSecurityHeaders };
تُستدعى في كل استجابة لواجهة البرمجة.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ماذا تحمي آلية CORS فعليًا؟
    • الخادم ضدّ الطلبات الآلية (curl، السكربتات)
    • مستخدم المتصفّح ضدّ عمليات القراءة غير المُصرَّح بها عبر المصادر
    • واجهة البرمجة ضدّ هجمات حجب الخدمة
  2. لماذا يتعارض Access-Control-Allow-Origin: * مع الطلبات التي ترسل ملفات تعريف ارتباط؟
    • ترفض المتصفّحات هذا المزيج لتجنّب كشف الجلسات المُصادَق عليها لأيّ موقع
    • يُرجِع الخادم خطأ 500 تلقائيًا
    • يُعطِّل الرمز البديل ملفات تعريف الارتباط على جانب الخادم
  3. تُرجِع واجهة برمجة مُصادَق عليها GET /invoices/42 لمستخدم لا يملك تلك الفاتورة. أيّ خطر من مخاطر OWASP لواجهات البرمجة هذا؟
    • الحقن (Injection)
    • كسر التخويل على مستوى الكائن (BOLA)
    • سوء تهيئة الأمان (Security Misconfiguration)
    • تزوير الطلب من جانب الخادم (Server-Side Request Forgery)