-
-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
469 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
title: DoS Prevention | ||
--- | ||
|
||
When the template or data context cannot be trusted, enabling DoS prevention options is crucial. LiquidJS provides 3 options for this purpose: `parseLimit`, `renderLimit`, and `memoryLimit`. | ||
|
||
## TL;DR | ||
|
||
Setting these options can largely ensure that your LiquidJS instance won't hang for extended periods or consume excessive memory. These limits are based on the available JavaScript APIs, so they are not precise hard limits but thresholds to help prevent your process from failing or hanging. | ||
|
||
```typescript | ||
const liquid = new Liquid({ | ||
parseLimit: 1e8, // typical size of your templates in each render | ||
renderLimit: 1000, // limit each render to be completed in 1s | ||
memoryLimit: 1e9, // memory available for LiquidJS (1e9 for 1GB) | ||
}) | ||
``` | ||
|
||
When a `parse()` or `render()` cannot be completed within given resource, it throws. | ||
|
||
## 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. For fully controlled rendering, consider using a process manager like [paralleljs][paralleljs]. | ||
|
||
## 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 filters in LiquidJS thus 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 | ||
[memoryLimit]: /api/interfaces/LiquidOptions.html#memoryLimit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
title: 防止 DoS 攻击 | ||
--- | ||
|
||
当模板或数据上下文不可信时,启用DoS预防选项至关重要。LiquidJS 提供了三个选项用于此目的:`parseLimit`、`renderLimit` 和 `memoryLimit`。 | ||
|
||
## TL;DR | ||
|
||
设置这些选项可以在很大程度上确保你的 LiquidJS 实例不会长时间挂起或消耗过多内存。这些限制基于可用的 JavaScript API,因此它们不是精确的硬性限制,而是确保你的进程不会失败或挂起的阈值。 | ||
|
||
```typescript | ||
const liquid = new Liquid({ | ||
parseLimit: 1e8, // 每次渲染的模板的典型大小 | ||
renderLimit: 1000, // 每次渲染最多 1s | ||
memoryLimit: 1e9, // LiquidJS 可用的内存(1e9 对应 1GB) | ||
}) | ||
``` | ||
|
||
## 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 次。 | ||
|
||
单个模板内的标签和过滤器仍然可能把进程挂起。要完全控制渲染过程,建议使用类似 [paralleljs][paralleljs] 的进程管理器。 | ||
|
||
## 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 | ||
[memoryLimit]: /api/interfaces/LiquidOptions.html#memoryLimit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.