الأمان والعمليات
لمحة سريعة
قسم بعنوان «لمحة سريعة»يرسل هذا الجسر لغة ترميز النص الفائق (HTML) لديك عبر حدود الشبكة إلى محرك متصفح. توثّق هذه الصفحة عناصر التحكم التي تحمي تلك الحدود، مع اعتماد الشيفرة المصدرية مرجعًا للحقيقة. عندما يستند عنصر تحكم إلى معيار، يكون الاستشهاد هو نفسه المعلن في كتلة توثيق الشيفرة. تعيد هذه الصفحة صياغة ما تؤكده الشيفرة؛ ولا تعيد بناء الصياغة المعيارية.
نموذج التهديد
قسم بعنوان «نموذج التهديد»تسمّي كتل توثيق الحزمة التهديدات التي تدافع ضدها:
- XSS-to-PDF — البرمجة عبر المواقع (XSS) عبر ترميز عدائي يُنفَّذ أثناء تصيير تنسيق المستندات المحمولة (PDF).
- SSRF — تزوير الطلب من جانب الخادم (SSRF) الناتج عن ترميز أو محدِّد موقع موارد موحَّد (URL) لوجهة ترسل طلبًا إلى عنوان داخلي.
- استنزاف الموارد — مُدخَل مفرط الحجم أو قنبلة فكّ ضغط.
- إعادة ربط DNS — إعادة الربط في نظام أسماء النطاقات (DNS)، حيث يجتاز اسم المضيف عملية التحقق ثم يُحلَّل إلى عنوان خاص عند وقت الاتصال.
- اعتراض TLS على المسار — اعتراض أمان طبقة النقل (TLS) على المسار عبر شهادة مستبدَلة على المسار إلى الـ Worker.
لكل تهديد عنصر تحكم محدد وقابل للاختبار أدناه.
ضوابط المُدخَلات (قبل أن يغادر الطلب PHP)
قسم بعنوان «ضوابط المُدخَلات (قبل أن يغادر الطلب PHP)»تُنفَّذ CloudflareSecurityPolicy::validate() قبل بناء أي طلب:
| الضابط | السلوك | مصدر الحدّ |
|---|---|---|
| حدّ الحجم | يرفض HTML الأكبر من maxHtmlSize | CloudflareRendererConfig، الافتراضي 5000000 بايت |
| حارس قنبلة فكّ ضغط Base64 | يقدّر الحجم بعد فكّ التشفير لكل URI من نوع data:…;base64,…؛ ويرفض القيم التي تبلغ الحدّ الأقصى أو تتجاوزه | MAX_DATA_URI_BYTES = 13631488 |
| حظر meta-refresh | يرفض أي <meta http-equiv="refresh">، دون حساسية لحالة الأحرف | تعبير نمطي في CloudflareSecurityPolicy |
تثير أي مخالفة RuntimeException برسالة تذكر القيمة المخالِفة والحدّ. يوجد حظر meta-refresh لأن توجيه التحديث يمكن أن يبدأ تنقّلًا داخل الصفحة التي يصيّرها الـ Worker — وهو ناقل SSRF يكمن في المحتوى لا في الـ URL.
تعمل سياسة أمان HTML من nextpdf/core (HtmlSecurityPolicyInterface، الافتراضي DefaultHtmlSecurityPolicy) عند طبقة التحليل وتكمّل فحوص طبقة النقل المذكورة أعلاه. استرجعها باستخدام getHtmlSecurityPolicy(). احقن سياسة مخصصة عبر الباني.
ضوابط الوجهة (SSRF وإعادة ربط DNS)
قسم بعنوان «ضوابط الوجهة (SSRF وإعادة ربط DNS)»CloudflareSecurityPolicy::validateWorkerUrl():
- يرفض أي URL يتعذّر تحليله أو يفتقر إلى scheme/host (
Invalid Worker URL). - يرفض أي مخطط غير HTTPS (
Worker URL must use HTTPS). - بالنسبة لمضيف بعنوان IP حرفي، يرفض النطاقات الخاصة أو المحجوزة باستخدام
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGEفي PHP. من الناحية العملية، يرفض هذا المساحة الخاصة في RFC 1918، وحلقة الاسترجاع (loopback)، وعناوين الربط المحلي في RFC 3927. تغطّي الاختبارات صراحةً رفض192.168.xو127.0.0.1و169.254.x. امتداد المرشّحات (filter) في PHP هو ما يقرّر الانتماء إلى النطاق؛ ولا تربط هذه الحزمة ذلك القرار ببند معيّن. يُذكر RFC 1918 وRFC 3927 هنا وصفيًا بوصفهما التعريفين المعروفين لتلك النطاقات. - بالنسبة لاسم المضيف، يُحلَّل كل سجلات A و AAAA باستخدام
dns_get_record()(وليسgethostbyname()، الذي يعيد الجواب الأول فقط)، ويُرفض المضيف إذا كان أي عنوان مُحلَّل خاصًا أو محجوزًا.
استخدام تحليل جميع السجلات مقصود. توثّقه كتلة توثيق الصنف بوصفه دفاعًا ضد مضيف يعيد عدة سجلات؛ إذ قد يختار البحث بسجل واحد العنوان العام، بينما يختار الاتصال اللاحق عنوانًا خاصًا. يطابق هذا ورقة OWASP SSRF Prevention Cheat Sheet: حلّ جوابَي A و AAAA كليهما للنطاق، وتطبيق فحص العنوان غير العام على مجموعة النتائج الكاملة.
تعيد validateWorkerUrl() مجموعة عناوين IP التي تم التحقق منها. قبل الإرسال مباشرةً، يستدعي المُصيِّر assertPinsStillValid(). يعيد هذا الاستدعاء تحليل المضيف ويرفض أي عنوان IP يظهر حديثًا (Worker URL DNS answer changed since validation — possible DNS rebinding attack). يغلق ذلك نافذة وقت-الفحص / وقت-الاستخدام بين التحقق والاتصال.
ضوابط النقل (PinnedCurlTransport)
قسم بعنوان «ضوابط النقل (PinnedCurlTransport)»عند وجود مجموعة عناوين IP تم التحقق منها أو مجموعة تثبيت لمعلومات المفتاح العام للموضوع (SPKI) و توفير ResponseFactory متوافق مع توصية معايير PHP رقم 17 (PSR-17)، يستخدم المُصيِّر Transport\PinnedCurlTransport بدلًا من عميل توصية معايير PHP رقم 18 (PSR-18) المحقون. يفرض النقل عناصر التحكم هذه عند طبقة مقبض cURL:
- DNS مثبَّت — يربط
CURLOPT_RESOLVEالمضيف:المنفذ بمجموعة عناوين IP التي تم التحقق منها، بحيث لا تجري libcurl بحثها الخاص عند وقت الاتصال. يجعل هذا الربط فحص DNS على مستوى المستخدم منطبقًا على الاتصال الفعلي؛ وبدونه قد تحلّ libcurl عنوانًا مختلفًا. - تثبيت المفتاح العام لـ TLS — يُضبط
CURLOPT_PINNEDPUBLICKEYمن مجموعة التثبيت المجمَّعة. يتّبع هذا RFC 7469 §2.6: يُقبل الاتصال المثبَّت عندما تتقاطع مجموعة بصمات SPKI التي يقدّمها الخادم مع مجموعة التثبيت المُهيَّأة، ويكون فشل التحقق من التثبيت غير قابل للاسترداد. تُطبَّع سلاسل التثبيت منsha256/<base64>إلى صيغةsha256//<base64>الخاصة بـ cURL؛ ويثير أي تثبيت مشوَّهInvalidSpkiPinException. - التحقق من TLS مُفعَّل —
CURLOPT_SSL_VERIFYPEER => true،CURLOPT_SSL_VERIFYHOST => 2. - لا إعادة توجيه تلقائية —
CURLOPT_FOLLOWLOCATION => false،CURLOPT_MAXREDIRS => 0. تُعرَض استجابة 3xx على طبقة السياسة بدلًا من أن تتبعها libcurl إلى مضيف لم يتم التحقق منه. تنصّ كتلة توثيق الصنف على أن هذا مقصود، حتى يُعاد التحقق من إعادات التوجيه بدلًا من اتّباعها بصمت. - مهلة صارمة — يُضبط
CURLOPT_TIMEOUTمنrenderTimeout(الافتراضي30ثانية).
يثير أي خطأ cURL أو متن غير نصي CloudflareRenderException مع رقم خطأ cURL ورسالته.
إرشادات تشغيلية للتثبيت
قسم بعنوان «إرشادات تشغيلية للتثبيت»يحمل التكوين pinnedPublicKeys وbackupPublicKeys بصورة منفصلة. يصف RFC 7469 §2.5 تثبيت النسخة الاحتياطية بوصفه بصمة لزوج مفاتيح ثانوي لم يُنشر بعد ويُحتفَظ به دون اتصال، ويعامله بوصفه مسار الاسترداد الأساسي لفشل التحقق من التثبيت غير المقصود. احتفظ بتثبيت نسخة احتياطية واحد على الأقل حتى لا يؤدي تدوير الشهادة إلى تعطيل نقطة النهاية. يتيح لك الحقل المنفصل التحقق من التدوير بشكل مستقل. من الناحية التشغيلية:
- ثبّت SPKI الخاص بالشهادة الطرفية أو بشهادة وسيطة تتحكم في تدويرها.
- هيّئ دائمًا تثبيت نسخة احتياطية للشهادة التالية قبل التدوير.
- تعطّل مجموعة تثبيت فارغة التثبيت؛ لا تستخدم ذلك إلا مع سلسلة شهادات مستقرة ومعروفة. التثبيت اختياري وفقًا للتكوين.
المصادقة ومعالجة الأسرار
قسم بعنوان «المصادقة ومعالجة الأسرار»- يحمل طلب الـ Worker
Authorization: Bearer <apiToken>.apiTokenهو#[SensitiveParameter]، لذلك تحجبه آثار التتبّع. يرسل مسبار الوصول ترويسة الحامل نفسها عبرHEADلبروتوكول نقل النص الفائق (HTTP). - مفاتيح وصول Cloudflare R2 (
accessKeyId،secretAccessKey) هي#[SensitiveParameter]وتُستخدم فقط لاشتقاق مفتاح توقيع Amazon Web Services (AWS) Signature V4. - يقارن
ApiKeyValidatorالمفاتيح باستخدامhash_equals()(آمن من حيث التوقيت) ويدعم تخزين المفاتيح المُجزّأة بخوارزمية التجزئة الآمنة 256 (SHA-256) عبرvalidateHashed(). - كائنات التكوين هي
final readonly— لا يمكن تعديل سرّ ضُبط مرة واحدة. - استمدّ الأسرار من متغيرات البيئة أو من مدير أسرار. لا تودِعها في الشيفرة أبدًا. تتّبع الحزمة خط الأساس الأمني الأوسع لـ NextPDF: PHPStan Level 10، و
declare(strict_types=1)في كل ملف، ودونeval()/exec()، وإجراءات GitHub Actions مثبَّتة على SHA.
ما لا تؤكده هذه الحزمة
قسم بعنوان «ما لا تؤكده هذه الحزمة»- لا تنصّ على أي حدّ لمنصة Cloudflare (وقت معالج الـ Worker، أو الذاكرة، أو الحدّ الأقصى لمتن الطلب، أو عدد الطلبات الفرعية). حدود الحجم والوقت الوحيدة التي ينصّ عليها هذا التوثيق هي تلك التي تفرضها الحزمة بنفسها، والمذكورة أعلاه وفي /integrations/cloudflare/configuration/. للاطلاع على حدود المنصة، راجع التوثيق الرسمي لـ Cloudflare وتنفيذ الـ Worker لديك.
- لا توقّع ملفات PDF ولا تقدّم أي ادّعاء بمطابقة التوقيع. عندما تُطلب التواقيع، صيّر هنا، ثم وقّع بالمحرك. يوفّر NextPDF Pro توقيع التواقيع الإلكترونية المتقدمة لـ PDF (PAdES) B-B فقط؛ أما ملفات التحقق طويل الأمد فهي قدرة على مستوى Enterprise وتقع خارج نطاق هذا الجسر.
- لا تشهد بأن خط الأنابيب “tamper-proof” ولا تضمن ذلك ولا تجعله كذلك. تنفّذ فقط الضوابط المحددة القابلة للتحقق من المصدر الموصوفة في هذه الصفحة.
دليل التشغيل العملياتي
قسم بعنوان «دليل التشغيل العملياتي»| العَرَض | الفحص الأول |
|---|---|
Worker URL must use HTTPS | تحقّق من مخطط workerUrl المُهيَّأ. |
private or reserved IP | سجلات DNS لاسم مضيف الـ Worker؛ ابحث عن سجل يُحلَّل إلى مساحة RFC 1918 / loopback / RFC 3927. |
DNS answer changed since validation | عدم استقرار DNS أو محاولة إعادة ربط؛ أعد التحليل وافحص مجموعة السجلات الكاملة. |
cURL transport error | مسار الشبكة، وسلسلة TLS، و — إذا كانت التثبيتات مضبوطة — تحقق مما إذا كان SPKI للشهادة المقدَّمة لا يزال ضمن مجموعة التثبيت. |
| تفشل عمليات التصيير فور تدوير الشهادة | مجموعة تثبيت بدون تثبيت نسخة احتياطية مطابق. أضف SPKI الجديد كنسخة احتياطية قبل التدوير. |
is not installed / no LocalRendererFactoryInterface | الاحتياط مُفعَّل لكن لا يوجد مصنع موصول، أو nextpdf/artisan غائب. |
| رفض حدّ المعدّل غير متّسق عبر العُقَد | المُحدِّد في الذاكرة لكل عملية على حدة؛ ضع أمامه مخزنًا مشتركًا. |
الإبلاغ عن الحوادث
قسم بعنوان «الإبلاغ عن الحوادث»أبلِغ عن الثغرات عبر GitHub Security Advisories أو جهة الاتصال الأمنية في SECURITY.md الخاص بالمستودع. لا تُسجِّل المشكلات الأمنية بوصفها مشكلات GitHub عامة.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- /integrations/cloudflare/overview/ — لماذا صُممت هذه الحزمة حول الحدود.
- /integrations/cloudflare/configuration/ — حقول مجموعة التثبيت والحدود.
- /integrations/cloudflare/troubleshooting/ — التعيين الكامل من الإخفاق إلى الاستثناء.