跳转到内容

安全性与运维——CodeIgniter 4 上的 NextPDF

本页列出这套集成必须抵御的威胁,说明软件包源代码中实现的各项控制措施,并提供安全部署的运维规则。

有三个可能受攻击者影响的接口。

  1. 队列任务负载。 队列会存储任务数据。具有 broker(消息代理)访问权限的攻击者可以更改这些数据。这属于未经信任且已反序列化的输入。
  2. 响应文件名。 用户可以提供下载文件名。恶意文件名可能注入标头内容。
  3. 配置路径。 字体路径与签名路径都来自配置。错误路径可能导致读取或写入到错误位置。

队列任务会将负载视为未经信任且已反序列化的数据来处理。OWASP ASVS 要求对已反序列化的未信任数据执行安全的输入处理(ASVS V1.5.2)。

已验证的控制措施在 GeneratePdfJob 中实现:

  • builder(构建器)必须是非空字符串。任务会拒绝其他类型的值。
  • builder 必须符合 App\PdfBuilders\<Class>::<method> 这个格式。任务会拒绝任何其他 namespace(命名空间)、普通函数,以及带有前缀或后缀的负载。
  • builder 必须是可调用的。如果字符串符合格式但无法 resolve(解析)为可调用目标,任务会予以拒绝。

这些规则可防止通过篡改队列负载执行任意代码。软件包测试会逐一断言每一种拒绝情形。

任务会将文件写入磁盘。当应用程序为文件操作构建文件路径时,OWASP ASVS 要求进行安全的路径处理(ASVS V5.3.2)。

已验证的控制措施在 GeneratePdfJob 中实现:

  • 输出路径必须是非空字符串。
  • 任务会对路径进行规范化。它会在任何检查之前先解析 ... 路径段,并转换分隔符。
  • 规范化后的路径必须位于 WRITEPATH/pdfs/ 之内。任务会拒绝共用名称前缀的同级目录(pdfs-evil/)。
  • 路径必须以 .pdf 结尾(不分大小写)。

这些规则可防止通过篡改负载进行任意文件写入。

PdfResponse 会为每个 PDF 响应附加一组固定标头:

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

文件名写入标头之前会先经过清理。软件包会移除路径分隔符、null 字节以及 CR/LF。对于带引号的形式,它会转义双引号。对于非 ASCII 的名称,它会加上 RFC 5987 的 filename*=UTF-8''… 参数。空白名称会转换为 document.pdf

字体注册表会拒绝包含流包装器(stream wrapper,://)或 null 字节的 fontsPath。它会引发运行时错误。这可以阻止 php://phar:// 这类包装器路径。

控制措施 5——最小化的 service-locator 接口

标题为“控制措施 5——最小化的 service-locator 接口”的章节

CodeIgniter 4 没有 PSR-11 container(容器),而是使用 Services locator(服务定位器)。PSR-11 §1.3 将 service-locator 模式视为不建议使用(modal SHOULD NOT)。软件包有意将定位器接口保持精简。每个服务都是一个具名的 factory(工厂)方法。请在 controller(控制器)边界处解析服务,并把具体对象向内传递。请勿把 Services 类传入领域代码。

签名与 TSA 运维作业(NextPDF Pro/Enterprise)

标题为“签名与 TSA 运维作业(NextPDF Pro/Enterprise)”的章节

签名服务默认处于停用状态。只有当 signature.enabledtrue,且 signature.certificate 为非空值时,它才会启用。软件包默认的签名级别为 B-B。NextPDF Pro 提供 B-B 基准签名。长期验证(LTV)是另一项独立的 Enterprise 功能。它记录在 Premium 参考文档中,不在此处说明。

运维规则:

  • 请勿将证书与密钥文件纳入版本控制。请通过 .env 或机密管理工具提供它们。
  • 在生产环境中,请将 tsa.allow_insecure_http 保持为 false。明文 TSA 通道不可接受。
  • 当 TSA 发布稳定的密钥时,请设置 tsa.pinned_public_keys。请将 tsa.warn_on_key_rotation 保持为 true
  • 请将密钥文件的读取权限限制为应用程序用户可读。
  • 请在 composer.lock 中锁定所有已解析的版本。
  • 请在运行 worker 的应用程序中添加 codeigniter4/queue 依赖。
  • 请以低权限用户身份运行队列 worker。仅授予它对 WRITEPATH/pdfs/ 的写入权限。
  • 请让 worker 具备与 web 层相同的 NextPDF 扩展。已签名的 PDF 需要在 worker 环境中安装 NextPDF Pro 或 Enterprise。
  • 请在每个会构建 PDF 的运行环境中,确认已安装 mbstringzlib 扩展。
  • 请确认响应标头经过反向代理后仍会保留下来。
  • 请记录 PDF 生成作业及其上下文信息。请勿记录证书内容或密钥密码。
  • 队列负载的处理方式符合 OWASP ASVS V1.5.2。
  • 队列输出路径的处理方式符合 OWASP ASVS V5.3.2。
  • 定位器的设计遵循 PSR-11 §1.3 的指引。

NextPDF core 采用 Apache-2.0。安装 NextPDF Pro 或 Enterprise 后,签名信任锚点与 TSA 强化才会生效。CodeIgniter 软件包会公开对应的服务方法;在尚未安装相符的 Premium 软件包时,这些方法会返回 null。详见 </get-license/?intent=codeigniter-signing>。

  • /integrations/codeigniter/production-usage/ ——正确的队列注册与派发。
  • /integrations/codeigniter/configuration/ ——签名、TSA,以及路径相关的键。
  • /integrations/codeigniter/troubleshooting/ ——已验证的拒绝消息。
  • /integrations/codeigniter/overview/ ——完整的 API 接口。