跳到內容

NextPDF Symfony 安全性與維運

回應輔助方法會套用一組固定的安全性標頭。非同步訊息 DTO 會對輸出路徑進行兩次驗證。簽章是選用功能;在 Pro 層級下,僅限本文記載的 baseline 設定檔。

NextPDF\Symfony\Http\PdfResponse 會對其建構的每個回應(內嵌、下載,以及兩種串流變體)套用同一組標頭。對照原始常數驗證後,確切標頭如下:

標頭
Cache-Controlprivate, max-age=0, must-revalidate
Pragmapublic
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Content-Security-Policydefault-src 'none'
X-Robots-Tagnoindex, nofollow
Referrer-Policyno-referrer

這些設定可降低所產生文件遭 content-type 探測、遭 Framework(框架)內嵌、被 Index(索引)收錄,以及 referrer 外洩的風險。緩衝變體會額外設定 Content-Type: application/pdfContent-Length。串流變體會設定 content type,但刻意省略 Content-Length

這組標頭由套件固定設定。若要新增或變更標頭(例如為已驗證的下載套用更嚴格的 Cache-Control),請在控制器中於回傳前先異動回傳的 Response

PdfResponse 會以防禦性方式建構 Content-Disposition 標頭,且已由 PdfResponseTest 驗證:

  • 檔名會經過淨化;路徑分隔字元與遍歷序列都會被移除(像 ../../../etc/passwd.pdf 這樣的檔名無法逸出)。
  • 缺少副檔名時會附加 .pdf;既有副檔名不會被重複附加,包括大寫的 .PDF
  • 雙引號與反斜線會針對 quoted-string 格式進行跳脫。
  • 非 ASCII 檔名會取得一個 ASCII 後援字串 以及 一個 RFC-5987 的 filename*=UTF-8'' 變體。
  • 空白檔名會退回為 document.pdf

只有在你已完成應用層級的授權檢查後,才可傳入受使用者影響的檔名;此套件的淨化只確保標頭安全,並非用於存取控制。

NextPDF\Symfony\Message\GeneratePdfMessage 會在建構式中驗證輸出路徑,而 NextPDF\Symfony\Message\GeneratePdfHandler 會在寫入前的執行階段再次驗證。已驗證的建構時拒絕規則如下:

  • 空白路徑,或包含 null byte 的路徑;
  • php://... 這類 stream-wrapper scheme;
  • 含有 .. 遍歷片段,且使用 /\ 任一分隔字元;
  • 未以 .pdf 結尾(不分大小寫)的路徑;
  • 語法上並非有效類別名稱的 builderClass

處理器中的第二次驗證之所以重要,是因為訊息可能在派送與消費之間停留在佇列中。處理器不信任佇列中的路徑,會在儲存前再次套用路徑防護。請以最小權限的檔案系統帳號執行 worker,並將其範圍限制在預期的輸出目錄。

GeneratePdfHandler 會從以類別名稱為鍵的 PSR-11 service locator 解析建構器,並拒絕任何未實作 PdfBuilderInterface 的服務。由於 locator 只會公開已註冊的建構器,即使遭竄改的傳輸負載帶有受攻擊者控制的 builderClass,也無法實例化任意類別。依 PSR-11,當容器回報某個 id 不存在時,解析該 id 會失敗,而非靜默回傳非預期的東西(PSR-11 §1.1.2)。請只在 locator 中註冊受信任的建構器類別。

數位簽章 並非 核心套件的一部分。唯有當 nextpdf/premium(會安裝 Pro 層級)存在,且編譯器階段偵測到 Pro 簽章類別時,才會啟用。在已安裝此套件與 Pro 層級的情況下,受支援且有文件記載的簽章設定是 baseline B-B 設定檔。

為了讓 NextPDF 各設定家族維持 schema 相容性,signature.level 設定節點仍接受其他字串值。此套件交付並支援的簽章能力是 B-B。超出 B-B 的簽章設定檔、其需求及其維運考量,記載於 NextPDF Premium 文件中,本文刻意不予描述。

B-B 簽章路徑的維運注意事項:

  • 簽章器signature.enabled 為 true 已設定 signature.certificate 時才會註冊;否則此區段會保持惰性且不作用。
  • 請透過 Symfony secrets 或環境變數提供憑證、私密金鑰與密碼,絕不可提交到版本庫。
  • 請將金鑰素材的讀取權限限制為應用程式帳號。

字型與影像登錄器接受一個選用的 Psr\Log\LoggerInterface,並以 nullOnInvalid() 繫結。存在時,它會作為依 PSR-3 logger 合約可替換的協作元件(PSR-3)。請在你於文件產生流程周邊加入的任何記錄情境中,清除可識別使用者的資料;此套件不會記錄文件內容。

  • 請保留固定的回應標頭;在控制器層為已驗證的下載加上更嚴格的快取。
  • 請在產生或回傳文件前先授權該請求;此套件不會執行存取控制。
  • 請以最小權限的檔案權限保護簽章金鑰素材,並透過 Symfony secrets/環境變數提供。
  • 請以最小權限帳號執行 Messenger worker,並將其寫入權限限制在輸出目錄。
  • 請保持啟用 ext-mbstringext-zlib(否則此套件會快速失敗)。
  • 請在應用程式中固定單一的 nextpdf/core 主版本,讓引擎版本在各次部署間保持確定。

每一列都對應本頁提出的一項規範性主張,並釘選到受管制 SDO 語料庫中的完整 64-hex reference_id。provenance(來源資訊),也就是語料庫資訊清單與檢索傳輸,位於 _sidecars/rag-citations.yaml

規格條款參考 ID主張
PSR-11psr_11_container#1.1.2.p5has() 為 false 即代表 get() 會擲出 NotFoundException
PSR-3psr_3_logger#x3.p17選用的 logger 協作元件

唯有在安裝 nextpdf/premium(Pro)時,數位簽章才可用;此套件交付的設定檔是 baseline B-B。這是選用的 Pro 能力;本文記載的 Core 套件可在不變更任何程式碼的情況下採用。請參閱 </get-license/?intent=symfony-pro>。

  • /integrations/symfony/production-usage/ — worker 安全性與串流。
  • /integrations/symfony/configuration/ — signature、tsa 與服務對照表。
  • /integrations/symfony/troubleshooting/ — 診斷簽章與 Messenger 問題。
  • /integrations/symfony/integration/ — 端到端串接參考。