docs: reorganize security-model structure for clarity

Restructure English and Chinese security-model docs into a consistent flow: security boundary, limits overview, per-limit details, and online service guidance.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Yang Jun
2026-05-09 22:28:00 +08:00
co-authored by Cursor
parent 1e8ce453a5
commit 503429e4cd
2 changed files with 49 additions and 57 deletions
+26 -30
View File
@@ -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
+23 -27
View File
@@ -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