From 1e8ce453a5efb535a7dd131fa32b4c883cad8c8c Mon Sep 17 00:00:00 2001 From: Yang Jun Date: Sat, 9 May 2026 22:06:06 +0800 Subject: [PATCH] docs: merge DoS details into security-model docs Move the detailed parseLimit/renderLimit/memoryLimit explanations and examples into the English and Chinese security-model pages so content from the removed dos pages is preserved. Co-authored-by: Cursor --- docs/source/tutorials/security-model.md | 35 +++++++++++++++++++ docs/source/zh-cn/tutorials/security-model.md | 35 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/docs/source/tutorials/security-model.md b/docs/source/tutorials/security-model.md index 838d8cbac..fc6da6c74 100644 --- a/docs/source/tutorials/security-model.md +++ b/docs/source/tutorials/security-model.md @@ -39,6 +39,41 @@ LiquidJS provides 3 DoS-oriented options: For heavy single-template operations, process-level isolation is still recommended (for example with [paralleljs][paralleljs]). +## DoS limits details + +### parseLimit + +[parseLimit][parseLimit] restricts the size (character length) of templates parsed in each `.parse()` call, including referenced partials and layouts. Since LiquidJS parses template strings in near O(n) time, limiting total template length is usually sufficient. + +A typical PC handles `1e8` (100M) characters without issues. + +### renderLimit + +Restricting template size alone is insufficient because dynamic loops with large counts can occur in render time. [renderLimit][renderLimit] mitigates this by limiting the time consumed by each `render()` call. + +```liquid +{%- for i in (1..10000000) -%} + order: {{i}} +{%- endfor -%} +``` + +Render time is checked on a per-template basis (before rendering each template). In the above example, there are 2 templates in the loop: `order: ` and `{{i}}`, render time will be checked 10000000x2 times. + +For time-consuming tags and filters within a single template, the process can still hang. + +### memoryLimit + +Even with small number of templates and iterations, memory usage can grow exponentially. In the following example, memory doubles with each iteration: + +```liquid +{% assign array = "1,2,3" | split: "," %} +{% for i in (1..32) %} + {% assign array = array | concat: array %} +{% 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. + [paralleljs]: https://www.npmjs.com/package/paralleljs [parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit [renderLimit]: /api/interfaces/LiquidOptions.html#renderLimit diff --git a/docs/source/zh-cn/tutorials/security-model.md b/docs/source/zh-cn/tutorials/security-model.md index bb6a20f0b..be9cc7764 100644 --- a/docs/source/zh-cn/tutorials/security-model.md +++ b/docs/source/zh-cn/tutorials/security-model.md @@ -39,6 +39,41 @@ LiquidJS 提供 3 个 DoS 相关选项: 对于单个模板中的重型操作,仍建议使用进程级隔离(例如 [paralleljs][paralleljs])。 +## DoS 限制详解 + +### parseLimit + +[parseLimit][parseLimit] 限制每次 `.parse()` 调用中解析的模板大小(字符长度),包括引用的 partials 和 layouts。由于 LiquidJS 解析模板字符串的时间复杂度接近 O(n),限制模板总长度通常就足够了。 + +普通电脑可以很容易处理 `1e8`(100M)个字符的模板。 + +### renderLimit + +仅限制模板大小是不够的,因为在渲染时可能会出现动态的数组和循环。[renderLimit][renderLimit] 通过限制每次 `render()` 调用的时间来缓解这些问题。 + +```liquid +{%- for i in (1..10000000) -%} + order: {{i}} +{%- endfor -%} +``` + +渲染时间是在渲染每个模板之前检查的。在上面的例子中,循环中有两个模板:`order: ` 和 `{{i}}`,因此会检查 2x10000000 次。 + +单个模板内的标签和过滤器仍然可能把进程挂起。 + +### memoryLimit + +即使模板和迭代次数较少,内存使用量也可能呈指数增长。在下面的示例中,内存会在每次迭代中翻倍: + +```liquid +{% assign array = "1,2,3" | split: "," %} +{% for i in (1..32) %} + {% assign array = array | concat: array %} +{% endfor %} +``` + +[memoryLimit][memoryLimit] 限制内存敏感操作,以防止过度的内存分配。由于 [JavaScript 使用 GC 来管理内存](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management),`memoryLimit` 仅限制 LiquidJS 中已记账对象的总数,因此可能无法反映实际的内存占用。 + [paralleljs]: https://www.npmjs.com/package/paralleljs [parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit [renderLimit]: /api/interfaces/LiquidOptions.html#renderLimit