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

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

บริดจ์นี้ส่งเอกสารจากแอปพลิเคชันของคุณไปยังบริการภายนอกผ่านเครือข่าย จึงทำให้บริดจ์เป็นทั้งพื้นผิวคำขอฝั่งเซิร์ฟเวอร์และพื้นผิวความปลอดภัยของการรับส่งข้อมูล แพ็กเกจนี้ใช้การควบคุมที่เฉพาะเจาะจงและตรวจสอบได้สำหรับทั้งสองพื้นผิว แต่ไม่ได้รักษาความปลอดภัยของทั้งระบบด้วยตัวเอง การควบคุมเหล่านั้นจะทำงานได้ก็ต่อเมื่อคุณปรับใช้และดูแล Gotenberg พร้อมมาตรการป้องกันที่สอดคล้องกัน หน้านี้อธิบายการควบคุมที่แพ็กเกจใช้และหน้าที่ด้านการดำเนินงานที่ทำให้การควบคุมเหล่านั้นสมบูรณ์

ข้อความในหน้านี้ไม่ใช่การรับประกัน การควบคุมแต่ละรายการเป็นพฤติกรรมที่กำหนดไว้และมีการทดสอบครอบคลุม พร้อมข้อจำกัดที่ระบุไว้

บริดจ์ใช้นโยบายความปลอดภัยที่แตกต่างกันสองนโยบายในชั้นที่ต่างกัน:

  • นโยบายการรับส่งข้อมูล (GotenbergSecurityPolicy) — บังคับใช้สคีม URL คัดกรอง server-side request forgery (SSRF) ป้องกัน Domain Name System (DNS) rebinding จำกัดขนาดข้อมูลขาเข้า และคัดกรองชื่อไฟล์ นี่คือชั้นที่อธิบายไว้อย่างละเอียดด้านล่าง
  • นโยบายการแยกวิเคราะห์ HTML — นโยบายเนื้อหาในชั้นการแยกวิเคราะห์ ซึ่งใช้ค่านโยบายเริ่มต้นของคอร์ NextPDF และทำงานก่อนที่เนื้อหาจะไปถึงตัวเรนเดอร์ นโยบายนี้เสริมกับนโยบายการรับส่งข้อมูล แต่ยังคงเป็นอิสระจากนโยบายดังกล่าว หน้านี้ครอบคลุมนโยบายการรับส่งข้อมูล

บริดจ์คัดกรอง API URL ที่กำหนดค่าไว้ก่อนที่ไบต์ใดๆจะออกจากกระบวนการ การควบคุมนี้มีสามส่วน

การบังคับใช้สคีม ยอมรับเฉพาะ https เท่านั้น (ไม่คำนึงถึงตัวพิมพ์เล็กพิมพ์ใหญ่) URL ที่เป็น http:// แบบธรรมดาจะถูกปฏิเสธ ดังนั้น Transport Layer Security (TLS) จึงเป็นข้อบังคับสำหรับการแปลงทุกครั้งและการตรวจสอบสถานะ (health probe)

การคัดกรองที่อยู่ หากโฮสต์เป็น IP literal บริดจ์จะปฏิเสธเมื่อที่อยู่นั้นอยู่ในช่วงส่วนตัวหรือช่วงที่สงวนไว้ หากโฮสต์เป็นชื่อ บริดจ์จะรีโซลฟ์โฮสต์นั้นไปยังเรกคอร์ด A และ AAAA ทั้งหมด และปฏิเสธคำขอหากที่อยู่ที่รีโซลฟ์ได้ รายการใดรายการหนึ่ง เป็นที่อยู่ส่วนตัวหรือที่อยู่ที่สงวนไว้ การรีโซลฟ์เรกคอร์ดทั้งชุดแทนที่จะเป็นที่อยู่เดียวคือการควบคุมที่รับมือผู้โจมตีซึ่งซ่อนที่อยู่ส่วนตัวไว้หลังชื่อที่คืนที่อยู่สาธารณะร่วมด้วย วิธีนี้เป็นไปตามแนวทางการป้องกัน SSRF ของ OWASP: ดึงที่อยู่ IP ทั้งหมดที่อยู่เบื้องหลังชื่อโดเมน (เรกคอร์ด A และ AAAA สำหรับ IPv4 และ IPv6) และตรวจสอบความถูกต้องของแต่ละที่อยู่เทียบกับ allowlist (OWASP Cheat Sheet Series, SSRF prevention, application-layer defense; pinned ไว้ใน retrieval-augmented generation (RAG) sidecar ของหน้านี้)

การตรวจสอบซ้ำแบบ time-of-check/time-of-use (TOCTOU) บริดจ์จะรีโซลฟ์ใหม่และเปรียบเทียบกับชุดที่อยู่ที่บันทึกไว้ระหว่างการตรวจสอบความถูกต้อง ทันทีก่อนส่งคำขอ หากมีที่อยู่ใหม่ปรากฏขึ้น คำขอจะถูกยกเลิกพร้อมข้อผิดพลาด DNS-rebinding วิธีนี้ปิดช่องว่างระหว่างการตรวจสอบความถูกต้องกับการเชื่อมต่อ ซึ่งเป็นช่วงที่การโจมตีแบบ rebinding อาจใช้ประโยชน์ได้

เมื่อบริดจ์ใช้การรับส่งข้อมูลแบบ cURL-pinned ชุดที่อยู่ที่ตรวจสอบความถูกต้องแล้วจะถูกผูกกับการเชื่อมต่อด้วย CURLOPT_RESOLVE ดังนั้นเคอร์เนลจึงเชื่อมต่อไปยังที่อยู่ที่ผ่านการตรวจสอบแล้ว แทนที่จะเป็นที่อยู่ใดๆที่การค้นหา DNS ใหม่ ณ เวลาเชื่อมต่ออาจคืนกลับมา การติดตามการเปลี่ยนเส้นทางถูกปิดใช้งานบนการรับส่งข้อมูลนั้น (CURLOPT_FOLLOWLOCATION ปิด, CURLOPT_MAXREDIRS เป็นศูนย์) ดังนั้น 3xx จึงไม่สามารถส่งคำขอไปยังโฮสต์ที่ยังไม่ผ่านการตรวจสอบอย่างเงียบๆได้ ชั้นนโยบายจะได้รับการตอบสนองแทน

ผลกระทบด้านการดำเนินงาน SSRF guard ปฏิเสธที่อยู่ส่วนตัวและที่อยู่ที่สงวนไว้โดยการออกแบบ หาก Gotenberg ของคุณทำงานบนเครือข่ายส่วนตัว คุณไม่สามารถชี้บริดจ์ไปยังที่อยู่ส่วนตัวของ Gotenberg ได้ ให้เผยแพร่ Gotenberg ผ่านที่อยู่ที่ guard ยอมรับ และปกป้องเส้นทางนั้นด้วยการแบ่งกลุ่มเครือข่ายและการตรวจสอบสิทธิ์ ตามที่อธิบายไว้ในหัวข้อการปรับใช้ด้านล่าง

ความปลอดภัยของการรับส่งข้อมูลและการ pinning กุญแจสาธารณะ

หัวข้อที่มีชื่อว่า “ความปลอดภัยของการรับส่งข้อมูลและการ pinning กุญแจสาธารณะ”

การยืนยัน peer และโฮสต์ของ TLS เปิดใช้งานอยู่เสมอในการรับส่งข้อมูลแบบ cURL-pinned (CURLOPT_SSL_VERIFYPEER true, CURLOPT_SSL_VERIFYHOST 2) นอกจากการตรวจสอบความถูกต้องของห่วงโซ่มาตรฐานแล้ว บริดจ์ยังรองรับการ pinning แบบ SubjectPublicKeyInfo (SPKI)

แต่ละ pin เป็นแฮช SHA-256 ของ SubjectPublicKeyInfo ของเซิร์ฟเวอร์ แสดงในรูปแบบ sha256/<base64> บริดจ์ยอมรับใบรับรองเมื่อแฮช SPKI ของใบรับรองตรงกับ pin ใดๆในชุดรวมของ pin หลักและ pin สำรอง โมเดล pin สำรองนี้เป็นไปตาม RFC 7469 §4.3 ซึ่งระบุว่า pin สำรอง — ลายนิ้วมือของคู่กุญแจรองที่ยังไม่ถูกปรับใช้ — เป็นเส้นทางการกู้คืนหลักสำหรับความล้มเหลวในการตรวจสอบ pin ที่เกิดขึ้นโดยไม่ตั้งใจ และ §2.5 ซึ่งกำหนดให้ชุด pin ต้องมี pin อย่างน้อยหนึ่งรายการที่ไม่ปรากฏในห่วงโซ่ใบรับรองปัจจุบัน (RFC 7469 §4.3 และ §2.5; pinned ไว้ใน RAG sidecar ของหน้านี้) โค้ดของบริดจ์ประกาศ RFC 7469 §2.1 และ §2.6 สำหรับความหมายเชิงตรรกะของ pin สำรองอย่างน้อยหนึ่งรายการและการตัดกันของชุดรวม การ pinning เป็นแบบเลือกเปิดใช้งาน: เมื่อไม่ได้กำหนดค่า pin ไว้ จะใช้การตรวจสอบความถูกต้องของห่วงโซ่มาตรฐานและจะไม่บังคับใช้การ pinning

pin ที่แยกวิเคราะห์ไม่ได้จะทำให้เกิดข้อผิดพลาดของการกำหนดค่าก่อนคำขอใดๆ ใบรับรองที่ใช้งานจริงซึ่ง SPKI ไม่ตรงกับ pin ที่กำหนดค่าไว้รายการใดเลยจะทำให้คำขอล้มเหลวในชั้นการรับส่งข้อมูล — โดยการออกแบบ

การหมุนเวียนที่ผิดพลาดจะทำให้บริดจ์ติดต่อบริการไม่ได้ หมุนเวียนโดยไม่ให้เกิดการหยุดทำงาน:

  1. ก่อนเปลี่ยนกุญแจของเซิร์ฟเวอร์ ให้สร้าง SPKI pin สำหรับกุญแจใหม่ และเพิ่มเข้าไปในรายการ pin สำรอง จากนั้นปรับใช้การกำหนดค่านั้น บริดจ์จะยอมรับทั้งกุญแจปัจจุบันและกุญแจในอนาคต
  2. หมุนเวียนใบรับรองหรือกุญแจของเซิร์ฟเวอร์เพื่อใช้กุญแจใหม่
  3. ยืนยันว่าการแปลงยังคงสำเร็จ (กุญแจใหม่ตรงกับ pin สำรองแล้ว)
  4. ย้าย pin ใหม่จากรายการสำรองไปยังรายการหลัก และนำ pin ของกุญแจที่เลิกใช้งานออก จากนั้นปรับใช้
  5. สร้างและเตรียม pin สำหรับการหมุนเวียนครั้งถัดไปเป็น pin สำรองใหม่ เพื่อให้ชุด pin มีตัวสำรองที่ใช้งานได้อยู่เสมอ

การแยกรายการสำรองออกจากรายการหลักช่วยให้คุณเตรียมและตรวจสอบความถูกต้องของ pin ถัดไปได้โดยไม่ต้องแก้ไข pin ที่ใช้งานอยู่

เมื่อ apiKey มีค่า บริดจ์จะส่งค่านั้นเป็นเฮดเดอร์ Authorization: Bearer ในคำขอแปลง ฟิลด์นี้ถูกทำเครื่องหมายเป็น #[\SensitiveParameter] เพื่อให้ค่าถูกปกปิดออกจาก stack trace บริดจ์ไม่ได้โหลดข้อมูลลับให้คุณ ให้จัดหาข้อมูลลับจาก secret manager เมื่อกระบวนการเริ่มต้น และอย่า commit ข้อมูลลับนั้นเด็ดขาด โทเค็นจะไม่ถูกเขียนลงในบันทึกคำขอ — รายการดีบักที่บันทึกไว้มีเพียง URL ชื่อไฟล์ รูปแบบ และความยาวเนื้อหาเท่านั้น

การตอบสนองจะถูกยอมรับก็ต่อเมื่อสถานะเป็น 200 Content-Type มี application/pdf และเนื้อหาเริ่มต้นด้วยลายเซ็น %PDF การตรวจสอบลายเซ็นระดับไบต์มีความสำคัญ เพราะการประกาศประเภทเนื้อหาเพียงอย่างเดียวไม่ได้พิสูจน์ว่าไบต์เหล่านั้นคืออะไร มาตรฐาน WHATWG MIME Sniffing กำหนดเหตุผลเดียวกันนี้อย่างเป็นทางการในอัลกอริทึมการสนิฟประเภท MIME ซึ่งได้ประเภทที่คำนวณได้จากการจับคู่รูปแบบไบต์นำหน้า แทนที่จะมาจากประเภทที่ระบุไว้ แนวทางการอัปโหลดไฟล์ของ OWASP ระบุหลักการระดับแอปพลิเคชันที่สอดคล้องกัน: ตรวจสอบความถูกต้องของประเภทไฟล์และอย่าเชื่อเฮดเดอร์ Content-Type ที่ประกาศไว้ เพราะสามารถถูกปลอมแปลงได้ (WHATWG MIME Sniffing §6.2.3; OWASP Cheat Sheet Series, file-upload validation; pinned ไว้ทั้งคู่ใน RAG sidecar ของหน้านี้) บริดจ์ใช้การตรวจสอบที่เทียบเท่ากันในเชิงป้องกันที่ฝั่งขาเข้า: ความไม่ตรงกันจะทำให้เกิด typed exception และไบต์เหล่านั้นจะไม่ถูกส่งคืนเป็นผลลัพธ์โดยเด็ดขาด

ขอบเขตนี้ยังเป็นเหตุผลที่สัญญา PSR-18 มีความสำคัญในที่นี้ ไคลเอนต์ PSR-18 จะ throw ก็ต่อเมื่อไม่สามารถส่งคำขอได้หรือไม่สามารถแยกวิเคราะห์การตอบสนองให้เป็นออบเจกต์ PSR-7 ได้ — โดยจะไม่ throw เมื่อพบรหัสสถานะที่เป็นข้อผิดพลาด การตอบสนอง 4xx/5xx ที่มีรูปแบบถูกต้องจะถูกคืนค่ากลับไปยังผู้เรียกตามปกติ (PSR-18, “Exceptions”; pinned ไว้ใน RAG sidecar ของหน้านี้) ดังนั้นบริดจ์จึงตรวจสอบสถานะ ประเภท และลายเซ็นด้วยตนเอง แทนที่จะสมมติว่าการตอบสนองที่คืนกลับมาสำเร็จ ความหมายของ HTTP สำหรับการละเมิดข้อจำกัด content-type — การปฏิเสธ 415 (Unsupported Media Type) ซึ่งเซิร์ฟเวอร์ปฏิเสธเนื้อหาในรูปแบบที่ไม่รองรับ — คือโมเดลที่การตรวจสอบขาเข้าเลียนแบบ (RFC 9110 §15.5.16; pinned ไว้ใน RAG sidecar ของหน้านี้)

บริดจ์มีขีดจำกัดทรัพยากรภายในกระบวนการหนึ่งรายการ: maxFileSize (ค่าเริ่มต้น 52,428,800 ไบต์ = 50 MiB) มีการบังคับใช้ก่อนคำขอ ดังนั้นข้อมูลขาเข้าที่เกินขนาดจะไม่ไปถึงบริการโดยเด็ดขาด บริดจ์ไม่มีขีดจำกัดการทำงานพร้อมกัน ขีดจำกัดอัตรา หรือเพดานขนาดเอาต์พุตที่ติดตั้งมาในตัว ส่วนเหล่านี้เป็นความรับผิดชอบของการปรับใช้และผู้เรียก (ดู /integrations/gotenberg/production-usage/) ตั้งค่า maxFileSize ให้เป็นค่าที่เล็กที่สุดเท่าที่เอกสารจริงของคุณต้องการ — เพดานที่เข้มงวดกว่าเป็นการควบคุม denial-of-service ที่ประหยัดกว่า

การปรับใช้และการรักษาความปลอดภัยของบริการ Gotenberg

หัวข้อที่มีชื่อว่า “การปรับใช้และการรักษาความปลอดภัยของบริการ Gotenberg”

บริดจ์จะปลอดภัยได้เท่ากับบริการที่บริดจ์เรียกใช้เท่านั้น คุณเป็นผู้ดำเนินงานบริการนั้น หน้าที่ด้านล่างทำให้การควบคุมข้างต้นสมบูรณ์

  • ทำการ terminate TLS หน้า Gotenberg คอนเทนเนอร์ของ Gotenberg สื่อสารด้วย HTTP แบบธรรมดาตามค่าเริ่มต้น บริดจ์ต้องใช้ HTTPS ดังนั้นให้วาง Gotenberg ไว้หลัง reverse proxy ที่ terminate TLS, ingress หรือ service mesh และชี้บริดจ์ไปยังเอนด์พอยต์ HTTPS ให้ pin SPKI ของ proxy หากคุณเปิดใช้งานการ pinning
  • อย่าเผยแพร่ Gotenberg ต่อสาธารณะ Gotenberg แปลงเอกสารด้วยเอนจินระดับ LibreOffice และ Chromium และไม่ใช่บริการที่ควรเผยแพร่สู่อินเทอร์เน็ต จำกัด ingress ให้เฉพาะโฮสต์แอปพลิเคชันที่เรียกใช้ Gotenberg โดยใช้นโยบายเครือข่ายหรือกฎไฟร์วอลล์
  • บังคับใช้การตรวจสอบสิทธิ์บนเส้นทาง บริดจ์จะส่ง bearer token เมื่อมีการกำหนดค่า ให้บังคับใช้โทเค็นนั้น (หรือ mutual TLS) ที่ proxy เพื่อให้คำขอที่ไม่ผ่านการตรวจสอบสิทธิ์ไม่สามารถไปถึงเอนจินการแปลงได้
  • กำหนดเวอร์ชันบริการให้เฉพาะเจาะจง บริดจ์สมมติว่ามีเส้นทางบริการเพียงสองเส้นทาง — /forms/libreoffice/convert และ /health ตรึงอิมเมจ Gotenberg ไว้ที่แท็ก patch ที่เฉพาะเจาะจง ตรวจสอบเส้นทางทั้งสองนั้นเทียบกับเวอร์ชันที่คุณปรับใช้ และตรวจสอบซ้ำทุกครั้งที่อัปเกรด
  • กำหนดขนาดความจุการแปลงอย่างรอบคอบ การแปลงแต่ละครั้งจะจอง worker ไว้ตลอดระยะเวลาของคำขอ กำหนดขนาดการปรับใช้ Gotenberg ให้เหมาะกับอัตราการแปลงพร้อมกันสูงสุดของคุณ และจำกัดจำนวนการแปลงที่กำลังดำเนินอยู่ทางฝั่งผู้เรียกให้สอดคล้องกัน ความจุเป็นคุณสมบัติของการปรับใช้ของคุณ ไม่ใช่ของแพ็กเกจนี้
  • ถือว่าข้อมูลขาเข้าของการแปลงไม่น่าเชื่อถือ เอกสารที่ส่งผ่านการแปลงจะถูกประมวลผลโดยเอนจินที่ซับซ้อน จำกัด maxFileSize แยกการปรับใช้ Gotenberg ออกจากระบบอื่น (เซกเมนต์เครือข่ายของตนเอง egress น้อยที่สุด ไม่มีการเข้าถึงบริการภายใน) และอัปเดต patch ของเอนจินให้เป็นปัจจุบันเสมอ
  • แพ็กเกจนี้ไม่ได้ “ปลอดภัยตามค่าเริ่มต้น”: การควบคุมต่างๆมีอยู่จริง แต่ขึ้นอยู่กับการปรับใช้และการกำหนดค่าที่ถูกต้อง
  • แพ็กเกจนี้ไม่ได้ทำให้การแปลง “ป้องกันการดัดแปลง” หรือทำให้เอาต์พุต “ได้รับการรับรอง” แพ็กเกจนี้ตรวจสอบความถูกต้องของการรับส่งข้อมูลและรูปร่างของการตอบสนอง แต่ไม่ได้รับรองเนื้อหาเอกสาร
  • แพ็กเกจนี้ไม่ได้ให้บริการการลงนาม การประทับเวลา หรือการตรวจสอบความถูกต้องในระยะยาว สิ่งเหล่านั้นเป็นเรื่องของการประมวลผลภายหลัง การรองรับ PAdES ของรุ่น Pro เป็นเพียงเบสไลน์ B-B เท่านั้น และไม่รวม B-T, B-LT หรือ B-LTA ไม่มีสิ่งใดในบริดจ์นี้ที่บ่งบอกถึงความสามารถด้านการประทับเวลาหรือ LTV
  • แพ็กเกจนี้ไม่รองรับ “ไฟล์ Office ทั้งหมด” แพ็กเกจนี้รองรับรูปแบบหกรูปแบบที่ระบุไว้ และปฏิเสธรูปแบบอื่นทั้งหมดก่อนคำขอใดๆ
  • /integrations/gotenberg/configuration/ — กฎการเลือกการรับส่งข้อมูลและโมเดล pin แบบเต็ม
  • /integrations/gotenberg/production-usage/ — การลองใหม่ การหมดเวลา การทำงานพร้อมกัน และความสามารถในการสังเกตการณ์
  • /integrations/gotenberg/troubleshooting/ — ทุก security exception และสาเหตุที่ทำให้เกิดแต่ละรายการ
  • /integrations/gotenberg/overview/ — โฟลว์การแปลงและโมเดลการพึ่งพา