diff --git a/docs/source/tutorials/security-model.md b/docs/source/tutorials/security-model.md index fc6da6c74..210d7b688 100644 --- a/docs/source/tutorials/security-model.md +++ b/docs/source/tutorials/security-model.md @@ -2,44 +2,23 @@ title: Security Model --- -LiquidJS provides DoS-oriented limits (`parseLimit`, `renderLimit`, `memoryLimit`) to reduce risk, but these limits are cooperative safeguards, not strict runtime isolation. +LiquidJS provides DoS-oriented limits (`parseLimit`, `renderLimit`, `memoryLimit`) to reduce risk. This page explains what each limit protects, and the security boundary you should assume in production. -## `memoryLimit` is cooperative +## Security boundary -`memoryLimit` tracks memory-sensitive allocations inside LiquidJS code paths that explicitly account for them. It is best-effort mitigation for template-driven abuse, not a strict heap cap. +The built-in limits are cooperative safeguards, not strict runtime isolation. -- It does **not** equal process RSS/heap usage. -- It does **not** sandbox JavaScript execution. -- It should be combined with process/container limits and request timeouts for production defense-in-depth. +- They do **not** equal process RSS/heap usage. +- They do **not** sandbox JavaScript execution. +- They should be combined with process/container limits and request timeouts for defense in depth. -## What it limits (and what it does not) - -`memoryLimit` only limits operations that LiquidJS itself counts. - -- Counted: memory-sensitive LiquidJS operations that call internal memory accounting. -- Not guaranteed counted: arbitrary user object behavior such as custom `toValue()`/`toString()` chains, or other host-side code that allocates outside LiquidJS accounting points. - -In other words, `memoryLimit` limits what LiquidJS counts, not every byte your process may allocate. - -## Guidance for online services - -If you run an online service, avoid rendering fully user-defined templates whenever possible. - -- Prefer curated templates or a restricted template subset. -- If user-defined templates are required, isolate rendering (worker/process/container), enforce OS/container memory and CPU limits, and apply request rate limits. -- Treat `parseLimit`/`renderLimit`/`memoryLimit` as one layer in a broader DoS defense strategy. - -## DoS limits quick reference - -LiquidJS provides 3 DoS-oriented options: +## Limits at a glance - [parseLimit][parseLimit]: limit total template size per `parse()` call. - [renderLimit][renderLimit]: limit total render time per `render()` call. - [memoryLimit][memoryLimit]: cooperatively limit memory-sensitive allocations counted by LiquidJS. -For heavy single-template operations, process-level isolation is still recommended (for example with [paralleljs][paralleljs]). - -## DoS limits details +## Limit details ### parseLimit @@ -63,6 +42,13 @@ For time-consuming tags and filters within a single template, the process can st ### memoryLimit +`memoryLimit` only limits operations that LiquidJS explicitly counts. + +- Counted: memory-sensitive LiquidJS operations that call internal memory accounting. +- Not guaranteed counted: arbitrary user object behavior such as custom `toValue()`/`toString()` chains, or other host-side code that allocates outside LiquidJS accounting points. + +In other words, `memoryLimit` limits what LiquidJS counts, not every byte your process may allocate. + Even with small number of templates and iterations, memory usage can grow exponentially. In the following example, memory doubles with each iteration: ```liquid @@ -72,7 +58,17 @@ Even with small number of templates and iterations, memory usage can grow expone {% endfor %} ``` -[memoryLimit][memoryLimit] restricts memory-sensitive filters to prevent excessive memory allocation. As [JavaScript uses GC to manage memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management), `memoryLimit` limits only the total number of objects allocated by memory-sensitive operations in LiquidJS and may not reflect the actual memory footprint. +As [JavaScript uses GC to manage memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management), `memoryLimit` may not reflect the actual memory footprint. + +## Online service guidance + +If you run an online service, avoid rendering fully user-defined templates whenever possible. + +- Prefer curated templates or a restricted template subset. +- If user-defined templates are required, isolate rendering (worker/process/container), enforce OS/container memory and CPU limits, and apply request rate limits. +- Treat `parseLimit`/`renderLimit`/`memoryLimit` as one layer in a broader DoS defense strategy. + +For heavy single-template operations, process-level isolation is still recommended (for example with [paralleljs][paralleljs]). [paralleljs]: https://www.npmjs.com/package/paralleljs [parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit diff --git a/docs/source/zh-cn/tutorials/security-model.md b/docs/source/zh-cn/tutorials/security-model.md index be9cc7764..b21e9f196 100644 --- a/docs/source/zh-cn/tutorials/security-model.md +++ b/docs/source/zh-cn/tutorials/security-model.md @@ -2,44 +2,23 @@ title: 安全模型 --- -LiquidJS 提供了面向 DoS 的限制选项(`parseLimit`、`renderLimit`、`memoryLimit`)来降低风险,但这些限制是协作式防护,不是严格的运行时隔离。 +LiquidJS 提供了面向 DoS 的限制选项(`parseLimit`、`renderLimit`、`memoryLimit`)来降低风险。本文按统一结构说明每个限制的作用范围,以及你在生产环境应采用的安全边界。 -## `memoryLimit` 是协作式限制 +## 安全边界 -`memoryLimit` 只会统计 LiquidJS 内部显式记账的内存敏感分配。它是针对模板滥用的“尽力而为”缓解机制,不是严格的堆内存上限。 +内置限制是协作式防护,不是严格的运行时隔离。 - 它**不等于**进程的 RSS/heap 实际占用。 - 它**不是** JavaScript 沙箱。 - 在生产环境中应结合进程/容器资源限制和请求超时做分层防护。 -## 它限制什么(以及不限制什么) - -`memoryLimit` 只限制 LiquidJS 自己统计到的操作。 - -- 会被统计:LiquidJS 内部调用了内存记账逻辑的内存敏感操作。 -- 不保证被统计:任意用户对象行为(例如自定义 `toValue()` / `toString()` 链)以及其他发生在 LiquidJS 记账点之外的宿主侧分配。 - -换句话说,`memoryLimit` 限制的是 LiquidJS 的“已记账分配”,而不是进程里每一个字节的分配。 - -## 在线服务建议 - -如果你运行在线服务,建议尽量避免渲染完全由用户定义的模板。 - -- 优先使用受控模板或受限模板子集。 -- 如果必须支持用户自定义模板,请隔离渲染(worker/进程/容器),并同时配置操作系统或容器级的内存/CPU 限额与请求限流。 -- 将 `parseLimit` / `renderLimit` / `memoryLimit` 视为 DoS 防护体系中的一层,而不是唯一防线。 - -## DoS 限制速查 - -LiquidJS 提供 3 个 DoS 相关选项: +## 限制速览 - [parseLimit][parseLimit]:限制每次 `parse()` 的模板总长度。 - [renderLimit][renderLimit]:限制每次 `render()` 的总渲染时间。 - [memoryLimit][memoryLimit]:协作式限制 LiquidJS 已记账的内存敏感分配。 -对于单个模板中的重型操作,仍建议使用进程级隔离(例如 [paralleljs][paralleljs])。 - -## DoS 限制详解 +## 限制详解 ### parseLimit @@ -63,6 +42,13 @@ LiquidJS 提供 3 个 DoS 相关选项: ### memoryLimit +`memoryLimit` 只限制 LiquidJS 显式记账到的操作。 + +- 会被统计:LiquidJS 内部调用了内存记账逻辑的内存敏感操作。 +- 不保证被统计:任意用户对象行为(例如自定义 `toValue()` / `toString()` 链)以及其他发生在 LiquidJS 记账点之外的宿主侧分配。 + +换句话说,`memoryLimit` 限制的是 LiquidJS 的“已记账分配”,而不是进程里每一个字节的分配。 + 即使模板和迭代次数较少,内存使用量也可能呈指数增长。在下面的示例中,内存会在每次迭代中翻倍: ```liquid @@ -72,7 +58,17 @@ LiquidJS 提供 3 个 DoS 相关选项: {% endfor %} ``` -[memoryLimit][memoryLimit] 限制内存敏感操作,以防止过度的内存分配。由于 [JavaScript 使用 GC 来管理内存](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management),`memoryLimit` 仅限制 LiquidJS 中已记账对象的总数,因此可能无法反映实际的内存占用。 +由于 [JavaScript 使用 GC 来管理内存](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management),`memoryLimit` 可能无法反映实际的内存占用。 + +## 在线服务建议 + +如果你运行在线服务,建议尽量避免渲染完全由用户定义的模板。 + +- 优先使用受控模板或受限模板子集。 +- 如果必须支持用户自定义模板,请隔离渲染(worker/进程/容器),并同时配置操作系统或容器级的内存/CPU 限额与请求限流。 +- 将 `parseLimit` / `renderLimit` / `memoryLimit` 视为 DoS 防护体系中的一层,而不是唯一防线。 + +对于单个模板中的重型操作,仍建议使用进程级隔离(例如 [paralleljs][paralleljs])。 [paralleljs]: https://www.npmjs.com/package/paralleljs [parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit