ข้ามไปยังเนื้อหา

ความปลอดภัยและการดำเนินงานสำหรับแพ็กเกจ NextPDF Laravel

แพ็กเกจตั้งค่า response header แบบคงที่สำหรับ Portable Document Format (PDF) ทำความสะอาดชื่อไฟล์ดาวน์โหลด ตรวจสอบเส้นทางผลลัพธ์ของคิวบน worker และส่งการเรียก Hypertext Transfer Protocol (HTTP) ไปยัง timestamp authority ผ่านไคลเอนต์ที่รับรู้ความเสี่ยง request forgery หน้านี้อธิบายโมเดลภัยคุกคามและการกำหนดค่าการดีพลอยที่มาตรการควบคุมแต่ละรายการต้องใช้

Terminal window
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

แพ็กเกจเชื่อมเอนจิน PDF เข้ากับเว็บเฟรมเวิร์ก คำขอ HTTP และทรานสปอร์ตของคิวจึงเป็นตัวกำหนดขอบเขตความน่าเชื่อถือ มาตรการควบคุมเหล่านี้ครอบคลุมการจัดการ response, payload ของงานที่ถูก deserialize และ HTTP ขาออกไปยัง timestamp authority

สินทรัพย์ภัยคุกคามมาตรการควบคุมในแพ็กเกจนี้การกำหนดค่าการดีพลอยที่จำเป็น
PDF HTTP responseการ sniff content-type, clickjacking และการจัดทำดัชนีชุด header แบบคงที่ที่ตั้งค่าบน PdfResponse factory ทุกตัวไม่มี; กำหนดค่า header ไม่ได้
ชื่อไฟล์ที่ดาวน์โหลดการฉีด header และการ traverse เส้นทางใน Content-Dispositionตัวทำความสะอาดชื่อไฟล์จะตัดตัวคั่นเส้นทาง อักขระควบคุม และ null byte ออกไม่มี; ตัวทำความสะอาดทำงานเสมอ
เส้นทางผลลัพธ์ของงานคิวการเขียนไฟล์โดยพลการผ่าน payload ที่ถูก serialize แล้วถูกดัดแปลงเส้นทางถูกตรวจสอบใน handle() บน workerกำหนดเส้นทางผลลัพธ์ให้ชี้ไปยังเส้นทางจัดเก็บที่ควบคุมได้
HTTP ขาออกไปยัง timestamp authority (TSA)การปลอมแปลงคำขอฝั่งเซิร์ฟเวอร์ (server-side request forgery) และการดัดแปลงข้อมูล plaintextไคลเอนต์ HTTP ที่รับรู้ถึง request forgery; บังคับใช้ HTTPS เว้นแต่จะอนุญาตอย่างชัดแจ้งคง tsa.allow_insecure_http = false ไว้; ปักหมุด Subject Public Key Info (SPKI)
สถานะที่ใช้ร่วมกันของ workerการรั่วไหลของสถานะข้ามคำขอใน worker ที่ทำงานต่อเนื่องยาวนานfont registry ที่ถูกล็อก; แคชภาพที่จำกัดขอบเขต; เอกสารที่ผูกกับ factoryตั้งค่า preload_fonts; จำกัดขอบเขตหน่วยความจำที่ระดับ container

factory PdfResponse ทุกตัวตั้งชุด header แบบคงที่ดังนี้:

  • Cache-Control: private, max-age=0, must-revalidate
  • Pragma: public
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Content-Security-Policy: default-src 'none'
  • X-Robots-Tag: noindex, nofollow
  • Referrer-Policy: no-referrer

ค่าเหล่านี้เป็นค่าคงที่ใน PdfResponse และไม่สามารถกำหนดค่าได้ ชุดทดสอบของแพ็กเกจตรวจสอบ header แต่ละตัวบนเมธอด factory ทุกเมธอด รวมถึงรูปแบบที่เป็นสตรีม

ชื่อไฟล์ดาวน์โหลดจะผ่านตัวทำความสะอาดก่อนส่งไปยัง header Content-Disposition ตัวทำความสะอาดจะลบตัวคั่นเส้นทาง อักขระควบคุม และ null byte ออก และสร้างพารามิเตอร์ filename*= ตาม Request for Comments (RFC) 5987 สำหรับชื่อที่ไม่ใช่ ASCII ชื่อไฟล์ว่างจะถูกแทนด้วย document.pdf

GeneratePdfJob serialize closure ลงในทรานสปอร์ตของคิว โดย worker จะตรวจสอบเส้นทางผลลัพธ์ภายใน handle() ไม่ใช่ที่จุด dispatch การตรวจสอบจะปฏิเสธสิ่งต่อไปนี้:

  • null byte ในเส้นทาง
  • สคีมาของ stream-wrapper (ตัวอย่างเช่น php://)
  • .. เซกเมนต์การ traverse เส้นทาง
  • เส้นทางใดก็ตามที่ไม่ลงท้ายด้วย .pdf (ไม่คำนึงถึงตัวพิมพ์ใหญ่หรือเล็ก)

การปฏิเสธแต่ละครั้งจะ raise InvalidArgumentException การตรวจสอบจะทำงานเมื่อ worker นำงานไปประมวลผล payload ที่ถูก serialize อยู่บนทรานสปอร์ต Redis หรือฐานข้อมูล และอาจถูกเปลี่ยนแปลงก่อนที่ worker จะอ่าน กำหนดเส้นทางผลลัพธ์ให้ชี้ไปยังไดเรกทอรีจัดเก็บที่ควบคุมได้ อย่าใช้ค่าที่ได้มาจาก input ของคำขอที่ยังไม่ผ่านการตรวจสอบ

เมื่อกำหนดค่า timestamp authority แล้ว แพ็กเกจจะผูก PHP Standard Recommendation (PSR)-18 Psr\Http\Client\ClientInterface ไคลเอนต์ PSR-18 ส่งคำขอ PSR-7 และคืนค่า response PSR-7 (PSR-18 §2) ไคลเอนต์ที่ผูกไว้จะห่อหุ้มไคลเอนต์ที่อิงกับ curl ด้วยชั้นที่รับรู้ถึง request forgery ไคลเอนต์นี้บังคับใช้ HTTPS เว้นแต่ tsa.allow_insecure_http จะถูกตั้งเป็น true อย่างชัดแจ้ง

timestamp authority เป็นความสามารถระดับ Premium แพ็กเกจ Core ที่อธิบายไว้ที่นี่จะผูกการเชื่อมต่อของไคลเอนต์ HTTP และไคลเอนต์ timestamp; ส่วนการลงนามเองต้องใช้ nextpdf/premium หน้านี้ไม่ได้อธิบายพฤติกรรม baseline ของ PDF Advanced Electronic Signatures (PAdES) ที่เกินกว่า B-B; baseline ระดับสูงกว่านี้อยู่นอกขอบเขต

แนวทางปฏิบัติการสำหรับ timestamp authority:

  1. คงค่า tsa.allow_insecure_http เป็น false ในการใช้งานจริง
  2. ตั้ง tsa.pinned_public_keys ให้เป็นแฮช SPKI แบบ base64 SHA-256 ของใบรับรอง timestamp authority (รูปแบบ RFC 7469)
  3. คงค่า tsa.warn_on_key_rotation เป็น true เพื่อให้มีการบันทึก SPKI ที่เปลี่ยนไปก่อนที่ใบรับรองที่ปักหมุดไว้จะหมดอายุ
  4. อ่านค่า tsa.url จากการกำหนดค่าที่เชื่อถือได้เท่านั้น หากผู้ปฏิบัติการสามารถตั้งค่าจากหน้าจอผู้ดูแลระบบได้ ให้ใช้ egress firewall หรือนโยบาย DNS เพื่อลดความเสี่ยงต่อ request forgery

ใช้ Psr\Log\LoggerInterface เพื่อการวินิจฉัย ส่งบริบทแบบมีโครงสร้าง ไม่ใช่สตริงที่แทรกค่าไว้แล้ว PSR-3 กำหนดให้การ escape placeholder เป็นหน้าที่ของ implementation ของ logger และระบุว่าผู้เรียกไม่ต้อง escape ค่าบริบทล่วงหน้า (PSR-3 §1.2) บันทึกคลาสของ exception ไม่ใช่ข้อความหรือ trace เพื่อลดรายละเอียดภายในที่ปรากฏในล็อก

resource: config/nextpdf.php (tsa hardening) + src/Laravel/NextPdfServiceProvider.php
<?php
declare(strict_types=1);
// .env — production timestamp-authority hardening
// NEXTPDF_TSA_URL=https://tsa.example.test
// NEXTPDF_TSA_ALLOW_INSECURE_HTTP=false
// NEXTPDF_TSA_WARN_ROTATION=true
return [
'tsa' => [
'url' => env('NEXTPDF_TSA_URL'),
'allow_insecure_http' => env('NEXTPDF_TSA_ALLOW_INSECURE_HTTP', false),
'warn_on_key_rotation' => env('NEXTPDF_TSA_WARN_ROTATION', true),
'pinned_public_keys' => [
// base64 SHA-256 SPKI hashes of the TSA certificate
],
],
];
  • ชุด response header เป็นแบบคงที่ แอปพลิเคชันที่ต้องการ Content Security Policy (CSP) ที่แตกต่างต้องประมวลผล response ภายหลังจากที่ factory คืนค่าแล้ว
  • การตรวจสอบเส้นทางจะทำงานบน worker เส้นทางที่ไม่ถูกต้องจะผ่าน dispatch() ไปได้และจะล้มเหลวก็ต่อเมื่องานรันเท่านั้น
  • tsa.allow_insecure_http = true จะยกเลิกการบังคับใช้ HTTPS และทำให้ความน่าเชื่อถือของ timestamp อ่อนแอลง จำกัดการใช้ไว้เฉพาะการพัฒนาบนเครื่องท้องถิ่น
  • font registry จะถูกล็อกหลังการ warmup; แพ็กเกจปฏิเสธความพยายามในการลงทะเบียนฟอนต์ขณะรันไทม์ใน worker ที่ทำงานต่อเนื่องยาวนานโดยเจตนา

มาตรการควบคุมความปลอดภัยใช้การดำเนินการกับสตริงและอาร์เรย์แบบ constant-time และไม่เพิ่มต้นทุนต่อคำขอที่วัดได้ การแจงฟอนต์ในการใช้งานครั้งแรกเป็นต้นทุนด้านการปฏิบัติการหลัก; โหลดฟอนต์ล่วงหน้าตอน worker บูตเพื่อหลีกเลี่ยงความหน่วงของคำขอแรก

หน้านี้เป็นเอกสารอ้างอิงสำหรับโมเดลภัยคุกคามของแพ็กเกจ ซอร์สโค้ดบังคับใช้มาตรการควบคุมเหล่านี้ และชุดทดสอบยืนยันมาตรการเหล่านั้น ตารางโมเดลภัยคุกคามและขั้นตอนของ timestamp authority ระบุการกำหนดค่าการดีพลอยที่ผู้ปฏิบัติการต้องจัดเตรียม

ข้ออ้างแหล่งที่มาข้อกำหนดรหัสอ้างอิง (reference_id)
ไคลเอนต์ PSR-18 ส่งคำขอ PSR-7 และคืนค่า response PSR-7PSR-18 HTTP Client§2
ผู้เรียกส่งบริบทล็อกแบบมีโครงสร้างโดยไม่ได้ escapePSR-3 Logger§1.2

RFC 7469 ว่าด้วยการปักหมุด SPKI ระบุรูปแบบที่ใช้โดยคีย์การกำหนดค่า tsa.pinned_public_keys แพ็กเกจใช้ค่าหมุด (pin) ที่ผู้ปฏิบัติการจัดหาให้ และไม่ได้ทำการนำ RFC ดังกล่าวไปใช้งานเอง

การลงนาม PAdES B-B และการผสานรวม timestamp authority ต้องใช้ nextpdf/premium ความสามารถระดับ Enterprise แบบตัวเลือกนี้ไม่จำเป็นต้องเปลี่ยนแปลงโค้ดในแพ็กเกจ Core ที่อธิบายไว้ที่นี่ ดูที่ https://nextpdf.dev/get-license/?intent=laravel-signing สำหรับรายละเอียด

  • /integrations/laravel/configuration/ — ทุกคีย์ของ TSA, signature และคิว
  • /integrations/laravel/production-usage/ — รูปแบบ dependency injection (DI) และการจัดการข้อผิดพลาด
  • /integrations/laravel/troubleshooting/ — เหตุใดการตรวจสอบเส้นทางจึงปฏิเสธ input
  • /integrations/laravel/boot-and-discovery/ — อายุการใช้งานของ binding ใน worker ที่ทำงานต่อเนื่องยาวนาน