mancha 0.24.1 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/docs/01_syntax.md +2 -0
- package/docs/06_ssr.md +3 -2
- package/docs/07_typescript.md +5 -5
- package/docs/10_security.md +204 -0
- package/package.json +2 -4
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ when you move to a bundler or render them on the server.
|
|
|
50
50
|
| [htmx][hx] 2.0.10 | 14,996 B | ✔️ | ❌ | ❌ | ❌ |
|
|
51
51
|
| [Svelte][sv] 5.56.9 | 15,106 B | ❌ | ✔️ | ✔️ | ❌ |
|
|
52
52
|
| [Alpine.js][al] 3.16.1 | 15,400 B | ✔️ | ❌ | ❌ | ❌ |
|
|
53
|
-
| **mancha 0.24.
|
|
53
|
+
| **mancha 0.24.2** | **19,852 B** | ✔️ | ✔️ | ✔️ | ✔️ |
|
|
54
54
|
| [React][re] 19.2.8 | 52,002 B | ❌ | ✔️ | ✔️ | ❌ |
|
|
55
55
|
| [Vue][vu] 3.5.41 | 54,171 B | ✔️ | ✔️ | ✔️ | ❌ |
|
|
56
56
|
|
|
@@ -78,6 +78,7 @@ from bundling a minimal app instead.
|
|
|
78
78
|
- **[TypeScript](./docs/07_typescript.md)**: Type safety and checking.
|
|
79
79
|
- **[Testing](./docs/08_testing.md)**: Testing your UI.
|
|
80
80
|
- **[Performance](./docs/09_performance.md)**: Performance monitoring and optimization.
|
|
81
|
+
- **[Security](./docs/10_security.md)**: What rendering a template grants it, and where the trust boundary is.
|
|
81
82
|
|
|
82
83
|
## AI Agents
|
|
83
84
|
|
package/dist/cli.js
CHANGED
|
@@ -141,5 +141,8 @@ const _args = yargs(hideBin(process.argv))
|
|
|
141
141
|
}
|
|
142
142
|
})
|
|
143
143
|
.demandCommand(1, "You need at least one command before moving on")
|
|
144
|
+
// Without this, a misspelled or made-up flag is silently ignored instead of
|
|
145
|
+
// telling the caller that whatever they asked for did not happen.
|
|
146
|
+
.strict()
|
|
144
147
|
.help().argv;
|
|
145
148
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/docs/01_syntax.md
CHANGED
|
@@ -76,6 +76,8 @@
|
|
|
76
76
|
|
|
77
77
|
To avoid violation of Content Security Policy (CSP) that forbids the use of `eval()`, `mancha` evaluates all expressions using a safe expression parser. This means that only simple expressions are allowed, but it supports many modern JavaScript features, including optional chaining, the spread operator, and arrow functions.
|
|
78
78
|
|
|
79
|
+
The parser exists to satisfy CSP, not to sandbox the expression: names resolve against the globals, so a template can reach anything a script tag could. See [Security](./10_security.md) for what that means for the templates you render.
|
|
80
|
+
|
|
79
81
|
**Note**: `mancha` only supports **single-statement** expressions. You cannot use semicolons (`;`) to separate multiple actions. For complex logic, define a function in your script and call it from the template.
|
|
80
82
|
|
|
81
83
|
For example:
|
package/docs/06_ssr.md
CHANGED
|
@@ -18,7 +18,8 @@ src/
|
|
|
18
18
|
You can run the following command to compile the site into a `public` folder:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
|
|
21
|
+
mkdir -p ./public
|
|
22
|
+
npx mancha render ./src/index.html --vars="$(cat ./src/vars.json)" --output="./public/index.html"
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
For a more complete example, see [examples/compiled](../examples/compiled).
|
|
@@ -57,7 +58,7 @@ For a more complete example, see [examples/express](../examples/express).
|
|
|
57
58
|
For servers hosted as worker runtimes, such as `Cloudflare Workers`, you will need to import a stripped down version of `mancha` that does not have the ability to read local files.
|
|
58
59
|
|
|
59
60
|
```js
|
|
60
|
-
import { Renderer } from "mancha/dist/worker";
|
|
61
|
+
import { Renderer } from "mancha/dist/worker.js";
|
|
61
62
|
import htmlIndex from "./index.html";
|
|
62
63
|
import vars from "./vars.json";
|
|
63
64
|
|
package/docs/07_typescript.md
CHANGED
|
@@ -62,16 +62,16 @@ npx mancha check src/index.html
|
|
|
62
62
|
npx mancha check src/index.html --strict
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
###
|
|
65
|
+
### Types Never Reach the Output
|
|
66
66
|
|
|
67
|
-
The `:types` attributes are only used for static analysis and have no runtime behavior
|
|
67
|
+
The `:types` attributes are only used for static analysis and have no runtime behavior, so rendering always removes them. There is no flag to opt in or out:
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
|
-
#
|
|
71
|
-
npx mancha render src/index.html --output public/index.html
|
|
70
|
+
# :types and data-types are stripped from the rendered output
|
|
71
|
+
npx mancha render src/index.html --output public/index.html
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
This holds for every render, in the browser as well as on the server: `:types` and `data-types` are dropped from each node as it is rendered.
|
|
75
75
|
|
|
76
76
|
### Type Checking with For-Loops
|
|
77
77
|
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
`mancha` templates are code, not data. A directive is an expression that the renderer evaluates, so
|
|
4
|
+
rendering a template is equivalent to running the JavaScript in it. There is no mode that changes
|
|
5
|
+
this: `mancha` does not attempt to contain a hostile template, and it does not ship a sanitizer.
|
|
6
|
+
|
|
7
|
+
The boundary is therefore the source of the template, not the content of the template:
|
|
8
|
+
|
|
9
|
+
- **Safe**: render templates you wrote, or that came from your repository, your build, or an author
|
|
10
|
+
you would give commit access to.
|
|
11
|
+
- **Unsafe**: render a template supplied by a user, pulled from a database of user content, or
|
|
12
|
+
fetched from a host you do not control.
|
|
13
|
+
|
|
14
|
+
Values are different from templates. Data you put in the store (a name, a search query, an API
|
|
15
|
+
response) is data, and the text sinks escape it. The rest of this page describes exactly which sinks
|
|
16
|
+
do that, and what a template can reach when you render one.
|
|
17
|
+
|
|
18
|
+
## Templates Are Programs
|
|
19
|
+
|
|
20
|
+
Every one of these evaluates its value as an expression against the renderer's scope:
|
|
21
|
+
|
|
22
|
+
| Directive | When it evaluates |
|
|
23
|
+
| -------------------------------------- | -------------------------------------------- |
|
|
24
|
+
| `:data` | At mount, and again on keyed `:for` reuse |
|
|
25
|
+
| `:text`, `:html`, `:class`, `:show`, `:if` | At mount, and whenever a dependency changes |
|
|
26
|
+
| `:for`, `:key`, `:bind` | At mount, and whenever a dependency changes |
|
|
27
|
+
| `:attr:{name}`, `:prop:{name}` | At mount, and whenever a dependency changes |
|
|
28
|
+
| `:on:{event}` | Every time the event fires |
|
|
29
|
+
| `{{ ... }}` in a text node | At mount, and whenever a dependency changes |
|
|
30
|
+
|
|
31
|
+
The `data-` forms (`data-text`, `data-on-click`, ...) are the same directives and behave
|
|
32
|
+
identically.
|
|
33
|
+
|
|
34
|
+
Three of them do more than evaluate an expression:
|
|
35
|
+
|
|
36
|
+
- `<include src="...">` and `<link rel="subresource" href="...">` fetch another document and
|
|
37
|
+
preprocess it with the same renderer. The included file's directives run with the same scope and
|
|
38
|
+
privileges as the page that included it. Nesting is bounded only by `maxdepth` (default 10), which
|
|
39
|
+
raises `Maximum recursion depth reached`.
|
|
40
|
+
- `:render="./module.js"` imports that module and calls its default export. Importing runs the
|
|
41
|
+
module's top-level code.
|
|
42
|
+
- `<template is="...">` registers a custom tag. Registration is **first-wins** and the registry is
|
|
43
|
+
shared by reference with every subrenderer, so a fragment rendered early can claim a tag name that
|
|
44
|
+
the rest of the application has not defined yet, and later definitions of that name are ignored.
|
|
45
|
+
|
|
46
|
+
### The expression scope includes the globals
|
|
47
|
+
|
|
48
|
+
Expressions are parsed by an expression parser rather than `eval()`, but that is a Content Security
|
|
49
|
+
Policy accommodation, not a sandbox. The scope proxy resolves a name against the local arguments,
|
|
50
|
+
then the store, then `globalThis`, so every global is in scope:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<!-- Reads the document's cookies. -->
|
|
54
|
+
<div :text="document.cookie"></div>
|
|
55
|
+
|
|
56
|
+
<!-- Reads local storage. -->
|
|
57
|
+
<div :text="localStorage.getItem('token')"></div>
|
|
58
|
+
|
|
59
|
+
<!-- On the server, reads the process environment. -->
|
|
60
|
+
<div :text="process.env.DATABASE_URL"></div>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Because ordinary objects are in scope too, `.constructor.constructor` reaches `Function`, and a
|
|
64
|
+
single-expression language becomes an arbitrary-statement one:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<!-- Runs at mount. -->
|
|
68
|
+
<div :text="({}).constructor.constructor('/* any code at all */')()"></div>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Anything you can do in a `<script>` tag on the page, a template you render can do. Rendering a
|
|
72
|
+
template is the same grant as adding a script tag to the page.
|
|
73
|
+
|
|
74
|
+
## Escaping, Sink By Sink
|
|
75
|
+
|
|
76
|
+
Escaping applies to the **values** flowing through a template you control, and it is real. Given a
|
|
77
|
+
value of `<img src=x onerror="...">`:
|
|
78
|
+
|
|
79
|
+
| Sink | Result |
|
|
80
|
+
| --------------------------- | ----------------------------------------------------------------- |
|
|
81
|
+
| `:text` | Escaped. Set as `textContent`; no element is created (see below) |
|
|
82
|
+
| `{{ ... }}` | Escaped. Set as text node content; no element is created |
|
|
83
|
+
| `:html` | Parsed as HTML. The element is created and its `onerror` fires |
|
|
84
|
+
| `:attr:{name}` | Written verbatim, including `javascript:` URLs and `on*` handlers |
|
|
85
|
+
| `:prop:{name}` | Assigned to the property directly, with no URL check |
|
|
86
|
+
|
|
87
|
+
`:html` goes further than parsing: the resulting fragment is rendered as a `mancha` template by a
|
|
88
|
+
subrenderer, so directives inside it execute, and in the browser a `<script>` element in that string
|
|
89
|
+
runs when it is inserted.
|
|
90
|
+
|
|
91
|
+
`:text` escapes markup, but it has one edge worth knowing: the text it writes **during mount** is
|
|
92
|
+
still visited by the text-node plugin afterwards, so a value that itself contains `{{ ... }}` is
|
|
93
|
+
evaluated as an expression. Values written by `:text` after mount are not rescanned, and neither is
|
|
94
|
+
the result of a `{{ ... }}` substitution. Prefer `{{ ... }}` for values whose content you do not
|
|
95
|
+
control. This is a bug rather than intended behavior, tracked as
|
|
96
|
+
[#104](https://github.com/fresho-dev/mancha/issues/104); this paragraph goes away when it is fixed.
|
|
97
|
+
|
|
98
|
+
So a value is safe in `{{ ... }}` and, with that caveat, in `:text`; it is unsafe everywhere else.
|
|
99
|
+
This matters most for the values you do not choose yourself:
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<!-- Safe: URL query parameters, form input and API responses are escaped here,
|
|
103
|
+
and the substituted text is not evaluated. -->
|
|
104
|
+
<p>Results for {{ $$search }}</p>
|
|
105
|
+
|
|
106
|
+
<!-- Unsafe: the same value is markup here, and executes. -->
|
|
107
|
+
<div :html="$$search"></div>
|
|
108
|
+
|
|
109
|
+
<!-- Unsafe: an attacker-controlled `javascript:` URL is written through unchanged. -->
|
|
110
|
+
<a :attr:href="$$next">Continue</a>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The rule of thumb: untrusted values may only reach `{{ ... }}`, and `:text` subject to the note
|
|
114
|
+
above. If you need untrusted markup, see
|
|
115
|
+
[Isolating Untrusted Content](#isolating-untrusted-content).
|
|
116
|
+
|
|
117
|
+
## Whatever You Mount Is A Template
|
|
118
|
+
|
|
119
|
+
Mounting is what turns markup into a program, and it applies to everything under the mount point.
|
|
120
|
+
The script tag form (`<script src="//unpkg.com/mancha" init>`) mounts `body` by default, so any
|
|
121
|
+
content your server wrote into the page is a template, whether you meant it to be one or not.
|
|
122
|
+
|
|
123
|
+
HTML-escaping does not help here, because `{{ ... }}` is ordinary text and survives escaping intact:
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<!-- A comment stored as: {{ (0).constructor.constructor('...')() }} -->
|
|
127
|
+
<!-- Escaped correctly by the server, and still evaluated at mount. -->
|
|
128
|
+
<p>{{ (0).constructor.constructor('...')() }}</p>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Escaping does stop the attribute forms — an escaped `"` cannot open a `:text` attribute — but the
|
|
132
|
+
text-node form needs no attribute at all. If a page carries content from your users, deliver it as a
|
|
133
|
+
store value rendered by `{{ ... }}`, write it into the DOM yourself after mount, or keep it outside
|
|
134
|
+
the mounted subtree.
|
|
135
|
+
|
|
136
|
+
## Isolating Untrusted Content
|
|
137
|
+
|
|
138
|
+
If you have to display content you do not control, keep it out of the renderer.
|
|
139
|
+
|
|
140
|
+
**Sandboxed iframe.** `mancha` needs `allow-scripts` to run at all, and the sandbox only helps if
|
|
141
|
+
the frame cannot reach back into your page:
|
|
142
|
+
|
|
143
|
+
```html
|
|
144
|
+
<!-- The frame runs, but cannot touch this document. -->
|
|
145
|
+
<iframe src="/untrusted" sandbox="allow-scripts"></iframe>
|
|
146
|
+
|
|
147
|
+
<!-- Do not do this: the two tokens together give the frame full access to the parent DOM. -->
|
|
148
|
+
<iframe src="/untrusted" sandbox="allow-scripts allow-same-origin"></iframe>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Never combine `allow-scripts` with `allow-same-origin` for content served from your own origin. If
|
|
152
|
+
the frame genuinely needs a same-origin document of its own, serve it from a different origin
|
|
153
|
+
instead, so the origin — not the sandbox attribute — is what separates it from your page.
|
|
154
|
+
|
|
155
|
+
**Render to inert HTML.** Render trusted templates on the server and send the result to the client
|
|
156
|
+
without loading `mancha` there. The output is plain HTML with no directives left in it, so the
|
|
157
|
+
client never evaluates anything. This works because the template being rendered is yours; it is not
|
|
158
|
+
a way to defuse a hostile template, which would still execute on the server (see below).
|
|
159
|
+
|
|
160
|
+
## Server-Side Rendering
|
|
161
|
+
|
|
162
|
+
Rendering on the server ([SSR](./06_ssr.md)) moves expression evaluation into your server process,
|
|
163
|
+
where the ambient scope is Node's rather than the browser's:
|
|
164
|
+
|
|
165
|
+
- Expressions can read `process`, and anything else on `globalThis` in that process.
|
|
166
|
+
- `<include>` resolves through `fetchLocal`, which reads from the filesystem. An absolute `src`
|
|
167
|
+
reads that path directly, so `<include src="/etc/passwd">` is a file read, not a template error.
|
|
168
|
+
- `:render` imports the module at that path and executes it.
|
|
169
|
+
|
|
170
|
+
Two consequences:
|
|
171
|
+
|
|
172
|
+
1. **Never assemble a template from request data.** Pass request data as store values, which is what
|
|
173
|
+
the SSR examples do — `new Renderer({ name, ...vars })` — and keep the HTML itself fixed. A
|
|
174
|
+
template string built by concatenating user input is a remote code execution bug, not an XSS bug.
|
|
175
|
+
2. **Never let a request choose the path you render or include.** `preprocessLocal(req.query.page)`
|
|
176
|
+
lets the caller read any file the process can read.
|
|
177
|
+
|
|
178
|
+
## What The Library Does Protect
|
|
179
|
+
|
|
180
|
+
These are real, and worth knowing precisely because their scope is narrow:
|
|
181
|
+
|
|
182
|
+
- **`safevalues` at DOM sinks.** Attributes written by the renderer's own bookkeeping go through
|
|
183
|
+
`safeElement.setPrefixedAttribute` with an allowlist of `:`, `style` and `class` prefixes;
|
|
184
|
+
relative-path rebasing for `<a>` and `<area>` goes through `safeAnchorEl` / `safeAreaEl`, which
|
|
185
|
+
drop `javascript:` URLs; injected stylesheets go through `safeStyleEl`. All of these operate on
|
|
186
|
+
values the renderer derived from the template itself. **They do not sanitize `:attr:` or `:prop:`
|
|
187
|
+
values**, which are set directly, as the table above shows.
|
|
188
|
+
- **`tsec` on the build.** `npm run build` type-checks with `tsec`, which bans unsafe DOM sinks
|
|
189
|
+
(`innerHTML`, `eval`, and friends) in `mancha`'s own source, with a small set of reviewed
|
|
190
|
+
exemptions. It constrains how the library is written; it says nothing about what a template does.
|
|
191
|
+
- **CSP compatibility, with a bonus.** Because expressions are parsed rather than `eval`-ed,
|
|
192
|
+
`mancha` runs under a policy with no `'unsafe-eval'`. That same policy also blocks the
|
|
193
|
+
`Function` escape described above: the expression fails and is logged as a failed evaluation. It
|
|
194
|
+
does **not** stop the rest — property reads and method calls on globals such as `document.cookie`
|
|
195
|
+
or `localStorage.getItem(...)` still work — so CSP narrows the blast radius of a hostile template
|
|
196
|
+
without containing it.
|
|
197
|
+
|
|
198
|
+
## Summary
|
|
199
|
+
|
|
200
|
+
- Render templates only from sources you trust. A template can do whatever a script tag can do.
|
|
201
|
+
- Untrusted **values** are fine in `{{ ... }}` and `:text`, and only there.
|
|
202
|
+
- Untrusted **markup** belongs in a cross-origin or `allow-scripts`-only iframe, never in `:html`.
|
|
203
|
+
- On the server, a hostile template is code execution on your server, and `<include>` is a file
|
|
204
|
+
read. Pass request data as store values, never as template text or template paths.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mancha",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"description": "Javscript HTML rendering engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -105,8 +105,6 @@
|
|
|
105
105
|
"ts-node": "^10.9.2",
|
|
106
106
|
"tsdown": "^0.18.3",
|
|
107
107
|
"tsec": "^0.2.8",
|
|
108
|
-
"tsx": "^4.21.0"
|
|
109
|
-
"typescript": "^5.9.3",
|
|
110
|
-
"yargs": "^17.7.2"
|
|
108
|
+
"tsx": "^4.21.0"
|
|
111
109
|
}
|
|
112
110
|
}
|