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 <[email protected]>
This commit is contained in:
Yang Jun
2026-05-09 22:06:06 +08:00
co-authored by Cursor
parent cd431aabd9
commit 1e8ce453a5
2 changed files with 70 additions and 0 deletions
+35
View File
@@ -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
@@ -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