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

ความปลอดภัยและการดำเนินงานสำหรับ compat-legacy

อะแดปเตอร์ใช้โมเดลความปลอดภัยของเอนจิน NextPDF และเพิ่มการเสริมความแข็งแกร่งบางส่วนเหนือ TCPDF 6.2.13 เดิมอย่างตั้งใจ หน้านี้ระบุอย่างชัดเจนว่าสิ่งใดพร้อมใช้งานและสิ่งใดไม่พร้อมใช้งานโดยไม่กล่าวเกินจริง โปรดอ่านส่วนการลงนามอย่างละเอียด เพราะขอบเขตของส่วนนั้นตั้งใจให้แคบ

อะแดปเตอร์เปลี่ยนพฤติกรรมเดิมของ TCPDF 6.2.13 สามอย่างเพื่อความปลอดภัย พฤติกรรมเหล่านี้ไม่สามารถกำหนดค่ากลับไปเป็นรูปแบบที่ไม่ปลอดภัยได้:

ประเด็นTCPDF 6.2.13 เดิมอะแดปเตอร์
การจัดการข้อผิดพลาดError() เรียก die() และยุติโปรเซสError() โยน RuntimeException ผู้เรียกสามารถตรวจพบและจับความล้มเหลวได้ โดยไม่มีการฆ่าโปรเซสอย่างเงียบ ๆ
การเรียกใช้ HTMLช่องทางหลบเลี่ยงอาจเรียกใช้ PHP จากมาร์กอัปได้ค่าคงที่ K_TCPDF_CALLS_IN_HTML ถูกกำหนดตายตัวเป็น false มาร์กอัปไม่สามารถกระตุ้นการเรียกใช้ PHP ได้
เอาต์พุตโดยตรงOutput() echo ไปยังบัฟเฟอร์เอาต์พุตที่กำลังทำงานอยู่เอาต์พุตผ่านบริดจ์ปลายทางที่ปลอดภัยและไม่ทำให้บัฟเฟอร์เอาต์พุตที่ผู้เรียกควบคุมเสียหาย

การเปลี่ยนแปลงการจัดการข้อผิดพลาดทำให้คุณสามารถตรวจพบความล้มเหลวได้ แทนที่จะสูญเสียโปรเซสไปจากการยุติ Open Worldwide Application Security Project (OWASP) Application Security Verification Standard (ASVS) 5.0 §16.5.3 ระบุว่าแอปพลิเคชันควรล้มเหลวอย่างนุ่มนวลและปลอดภัย รวมถึงป้องกันสภาวะ fail-open การเปลี่ยนจาก die เป็นการโยนนำหลักการนั้นมาใช้ การเสริมความแข็งแกร่งของ HTML ขจัด sink สำหรับการเรียกใช้โค้ดออกไป จงถือว่าโค้ดเดิมที่พึ่งพาพฤติกรรมแบบเก่าเป็นข้อบกพร่องที่ต้องแก้ไขระหว่าง /integrations/tcpdf-compat/migration/ ไดเจสต์ของอนุประโยคที่ตรึงไว้อยู่ในฟิลด์ citations ในส่วนหัว front-matter ของหน้า

อะแดปเตอร์เปิดเผย SetProtection() ของ TCPDF และส่งต่อให้ตัวจัดการความปลอดภัยมาตรฐานของเอนจิน NextPDF

  • ตัวจัดการมาตรฐานใช้ AES-256 พารามิเตอร์ $mode เดิมรับไว้เพื่อความเข้ากันได้ของลายเซ็นเมท็อดและถูกละเว้น ไม่มีวิธีเลือกไซเฟอร์ที่อ่อนแอกว่าผ่านเมท็อดนี้ เมื่อเปิดโหมดเข้มงวด $mode ที่ไม่ใช่ค่าเริ่มต้นจะโยนข้อยกเว้นเพื่อบังคับให้การย้ายระบบรับรู้ถึงเรื่องนี้ (ยืนยันไว้ใน tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php)
  • หากไม่มีการระบุรหัสผ่านเจ้าของ อะแดปเตอร์จะสร้างรหัสผ่านเจ้าของแบบสุ่มที่แข็งแกร่งทางการเข้ารหัสลับ แทนที่จะนำรหัสผ่านผู้ใช้มาใช้ซ้ำ วิธีนี้ป้องกันไม่ให้ผู้ที่มีสิทธิ์เข้าถึงระดับผู้ใช้ได้รับการควบคุมเอกสารระดับเจ้าของ
  • การเข้ารหัสลับแบบใช้ใบรับรอง (คีย์สาธารณะ) ไม่ได้ทำผ่าน SetProtection() อะแดปเตอร์ละเว้นพารามิเตอร์ $pubkeys ของเมท็อดนี้ ให้ใช้จุดเข้าใช้งานการเข้ารหัสลับคีย์สาธารณะสมัยใหม่ที่เปิดเผยบนอะแดปเตอร์ (setPublicKeyEncryption()) ซึ่งส่งต่อให้เอนจิน

พฤติกรรมการเข้ารหัสลับสะท้อนตัวจัดการความปลอดภัยมาตรฐานที่อธิบายไว้ใน ISO 32000-2 §7 อนุประโยคนั้นกำหนดรายการในพจนานุกรมการเข้ารหัสลับและตัวจัดการมาตรฐาน AES-256 ที่เอนจินใช้ เอกสารนี้ไม่ได้อ้างว่าเอาต์พุตเป็น “secure by default” หรือ “tamper-proof” แต่ระบุเพียงไซเฟอร์ที่ใช้และพฤติกรรมรหัสผ่านเจ้าของที่โค้ดนำมาใช้เท่านั้น ไดเจสต์ของอนุประโยคที่ตรึงไว้อยู่ในฟิลด์ citations ในส่วนหัว front-matter ของหน้า

examples/security-encryption.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);
$pdf->Cell(0, 10, 'Encrypted document');
// User password set; owner password auto-generated (strong, random).
$pdf->SetProtection([], 'user-secret');
$pdf->Output(__DIR__ . '/encrypted.pdf', 'F');

โปรดอ่านส่วนนี้ตามถ้อยคำอย่างเคร่งครัด ส่วนนี้ตั้งใจใช้ถ้อยคำอย่างระมัดระวัง

  • เมท็อด setSignature() และ addEmptySignatureAppearance() เดิมของ TCPDF ไม่ได้นำมาใช้งาน ในอะแดปเตอร์บนเอนจินหลัก ในโหมดเริ่มต้น เมท็อดเหล่านี้ไม่ทำอะไรเลย ในโหมดเข้มงวด เมท็อดเหล่านี้จะโยน TcpdfNotImplementedException ออกมา
  • การลงนามดิจิทัลไม่ใช่ความสามารถของชุดแจกจ่ายหลักผ่านอะแดปเตอร์นี้ การรองรับลายเซ็นระดับพื้นฐานต้องใช้ NextPDF รุ่นเชิงพาณิชย์
  • หากมีรุ่นเชิงพาณิชย์อยู่ อะแดปเตอร์จะเปิดเผยจุดเข้าใช้งานลายเซ็นสมัยใหม่ (setSignatureV2()) ที่ส่งต่อให้เอนจิน โปรไฟล์เริ่มต้นของจุดเข้าใช้งานนี้คือโปรไฟล์ baseline (B-B)
  • เอกสารนี้ไม่อ้างใด ๆ ว่ารุ่นใดผลิตโปรไฟล์ลายเซ็นแบบประทับเวลา การตรวจสอบความถูกต้องระยะยาว หรือแบบจัดเก็บถาวรผ่านอะแดปเตอร์นี้ โดยเฉพาะอย่างยิ่ง เอกสารนี้ไม่ยืนยันพฤติกรรม B-T B-LT หรือ B-LTA ข้อกำหนดระดับพื้นฐานของ PDF Advanced Electronic Signatures (PAdES) §6.1 กำหนดระดับพื้นฐานที่แตกต่างกันสี่ระดับ ได้แก่ B-B B-T B-LT และ B-LTA แต่ละระดับมีข้อกำหนดของตนเอง B-B คือระดับพื้นฐาน ส่วนระดับที่สูงกว่า (การประทับเวลา ระยะยาว การจัดเก็บถาวร) เป็นโปรไฟล์แยกต่างหากและมีข้อกำหนดเข้มงวดกว่า มีเพียงระดับพื้นฐาน B-B เท่านั้นที่อยู่ในขอบเขตของเอกสารชั้นความเข้ากันได้นี้ ระดับที่สูงกว่าอยู่นอกขอบเขตอย่างชัดเจน และไม่มีการอ้างสำหรับรุ่นใดที่นี่ ไดเจสต์ของอนุประโยคที่ตรึงไว้อยู่ในฟิลด์ citations ในส่วนหัว front-matter ของหน้า
  • เอกสารนี้ไม่ได้อ้างลายเซ็นแบบ “certified” “guaranteed” “legally valid” หรือ “eIDAS-qualified” ที่ใดเลย ความถูกต้องของการลงนาม นโยบายจุดยึดความเชื่อถือ และความถูกต้องตามกฎหมายเป็นความรับผิดชอบของรุ่นที่ทำการลงนามและโครงสร้างพื้นฐานคีย์สาธารณะ (PKI) ของผู้เรียก ไม่ใช่ของชั้นความเข้ากันได้นี้

หากการย้ายระบบของคุณต้องการการลงนาม จงถือว่าเป็นกระแสงานแยกต่างหาก คือนำอินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชัน (API) สำหรับลายเซ็นสมัยใหม่มาใช้บนรุ่นเชิงพาณิชย์ และตรวจสอบความถูกต้องของลายเซ็นที่ได้ด้วยตัวตรวจสอบอิสระ อย่าพึ่งพาการเรียก setSignature() ของ TCPDF ที่นี่ เพราะการเรียกนี้เป็น no-op

เมท็อด setTimeStamp() เดิมรับไว้เพื่อความเข้ากันได้ของลายเซ็นเมท็อดและส่งการแจ้งเตือนออกมา เมท็อดนี้ไม่ได้สร้างลายเซ็นแบบประทับเวลาผ่านอะแดปเตอร์นี้

แฟล็ก pdfa ของคอนสตรัคเตอร์รับไว้เพื่อความเข้ากันได้ของลายเซ็นเมท็อด ความสอดคล้องสำหรับการจัดเก็บถาวรแบบ PDF/A ต้องใช้ NextPDF รุ่นเชิงพาณิชย์ อะแดปเตอร์เปิดเผย enablePdfA() ซึ่งส่งต่อให้เอนจิน และเอนจินจะคืนค่าข้อผิดพลาดการกำหนดค่าที่ดำเนินการได้เมื่อไม่มีรุ่นที่จำเป็น อะแดปเตอร์ไม่ผลิตไฟล์ที่ไม่สอดคล้องอย่างเงียบ ๆ พร้อมกับอ้างว่าเป็น PDF/A

เอาต์พุตเป็น PDF 2.0 เสมอ (ISO 32000-2) ISO 32000-2 §7.5.2 ระบุว่าตัวเขียนที่สอดคล้องจะระบุเวอร์ชันเอกสารเป็น 2.0 และไม่ลดเวอร์ชันลงเป็นเวอร์ชันเก่ากว่าเมื่อบันทึก ดังนั้น setPDFVersion() จึงไม่สามารถตั้งเป้าหมายไปยังเวอร์ชันเก่ากว่าได้ (ดู /integrations/tcpdf-compat/method-coverage/ §4) ไดเจสต์ของอนุประโยคที่ตรึงไว้อยู่ในฟิลด์ citations ในส่วนหัว front-matter ของหน้า

  • ไม่มีการยุติโปรเซส เนื่องจาก Error() โยนข้อยกเว้นแทน die() จงห่อจุดเข้าเรนเดอร์ด้วย try/catch และจับคู่ความล้มเหลวกับสัญญาข้อผิดพลาดของแอปพลิเคชันของคุณ อย่าสันนิษฐานว่าการเรนเดอร์ที่ล้มเหลวจะยุติคำขอ
  • ความปลอดภัยของบัฟเฟอร์เอาต์พุต Output() กับ S คืนค่าเป็นไบต์ กับ F เขียนเป็นไฟล์ กับ E คืนค่าเป็นเนื้อหา Multipurpose Internet Mail Extensions (MIME) แบบ base64 ส่วน I/D จะกำหนดเส้นทางผ่านเส้นทางเอาต์พุตของเอนจิน ควรเลือกใช้ S หรือ F ในเวิร์กเกอร์และตัวจัดการ Hypertext Transfer Protocol (HTTP) เพื่อให้คุณควบคุมการตอบสนองเอง ดู /integrations/tcpdf-compat/production-usage/
  • โหมดเข้มงวดไม่ใช่การตั้งค่าสำหรับระบบจริง จงเก็บไว้สำหรับงานบูรณาการต่อเนื่อง (CI) หรืองานตรวจสอบ ข้อยกเว้นในเส้นทางการเรนเดอร์ของระบบจริงแย่กว่าพารามิเตอร์ที่ถูกลดทอนอย่างเงียบ ๆ
  • สุขอนามัยของค่าคงที่ จงนิยามค่าคงที่ PDF_* / K_* ก่อนสร้างอะแดปเตอร์ครั้งแรก แฟล็กที่เสริมความแข็งแกร่งสองตัว (K_TCPDF_CALLS_IN_HTML K_TCPDF_THROW_EXCEPTION_ERROR) ไม่สามารถผ่อนปรนได้ อย่าพยายามผ่อนปรนแฟล็กเหล่านี้
  • รหัสผ่านเจ้าของแบบสุ่ม หากคุณพึ่งพารหัสผ่านเจ้าของแบบกำหนดค่าตายตัว จงตั้งค่ารหัสผ่านนั้นอย่างชัดเจน มิฉะนั้น จะมีการสร้างรหัสผ่านสุ่มที่แข็งแกร่งหนึ่งรหัสต่อเอกสารและไม่สามารถกู้คืนได้
  • สำหรับเมท็อดรูปภาพ อะแดปเตอร์ปฏิเสธเส้นทางที่เป็น stream-wrapper ก่อนการอ่านระบบไฟล์ใด ๆ การตรวจหาประเภทรูปภาพ (TcpdfImages::getImageFileType) ถือว่าเส้นทาง scheme:// ใด ๆ รวมถึง phar:// php:// และ stream wrapper อื่น ๆ ของ PHP เป็น wrapper และข้ามการตรวจสอบ file_get_contents / getimagesize โดยถอยกลับไปอนุมานจากนามสกุลเท่านั้น วิธีนี้ปิดช่องทางโจมตี phar metadata-deserialization บนเป้าหมาย backport ของ PHP 7.4 ตัวเอนจินเองก็ปฏิเสธการฝังเส้นทางที่เป็น wrapper
  • อะแดปเตอร์ไม่ได้เพิ่มการตรวจสอบหรือทำความสะอาดเส้นทางสำหรับเส้นทางไฟล์ที่ส่งไปยังเมท็อดรูปภาพหรือเอาต์พุตเกินกว่าที่เอนจินทำ จงถือว่าเส้นทางและ URL ที่ผู้เรียกระบุมาเป็นข้อมูลที่ไม่น่าเชื่อถือที่ขอบเขตแอปพลิเคชันของคุณ
  • HTML ที่ส่งไปยังเมท็อด HTML ถูกเรนเดอร์โดยเอนจิน ไม่ใช่โดยตัวแยกวิเคราะห์ HTML ของ TCPDF sink สำหรับการเรียกใช้ PHP เดิมถูกปิดแล้ว แต่คุณยังคงควรถือว่า HTML ที่ผู้เรียกระบุมาเป็นข้อมูลนำเข้าที่ไม่น่าเชื่อถือ
  • การเข้ารหัสลับปกป้องความลับของเอกสารขณะอยู่นิ่งภายใต้ตัวจัดการมาตรฐาน การเข้ารหัสลับไม่ใช่สิ่งทดแทนความปลอดภัยในการขนส่งหรือการควบคุมการเข้าถึงในแอปพลิเคชันของคุณ
  • /integrations/tcpdf-compat/method-coverage/ — พฤติกรรมที่แน่นอนของ SetProtection() setSignature()
  • /integrations/tcpdf-compat/configuration/ — แฟล็กที่เสริมความแข็งแกร่งและกำหนดค่าไม่ได้สองตัว
  • /integrations/tcpdf-compat/production-usage/ — เวิร์กเกอร์ บัฟเฟอร์ การจัดการความล้มเหลว
  • docs/TCPDF_COVERAGE.md — เมทริกซ์ความครอบคลุมที่เชื่อถือได้
  • แพ็กเกจ NOTICE — คำชี้แจงการพัฒนาที่เป็นอิสระ