oxidejs 0.1.4 → 0.1.6
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 +31 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -133,3 +133,34 @@ Same factory as Vite: client stubs, `/_action`, and `dist/server.js`.
|
|
|
133
133
|
- No `wrangler dev` / workerd emulation
|
|
134
134
|
- No automatic `celld deploy`
|
|
135
135
|
- No Node-builtin polyfills — Vite `ssr.noExternal: true` is a hard-fail for stray Node imports
|
|
136
|
+
|
|
137
|
+
## Security
|
|
138
|
+
|
|
139
|
+
### Asset serving (`preset: "fetch"`)
|
|
140
|
+
|
|
141
|
+
The generated server serves static files from `dist/client/` (or the `public/` directory merged into it). These guards are active:
|
|
142
|
+
|
|
143
|
+
| Attack vector | Guard |
|
|
144
|
+
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
145
|
+
| **Traversal** (`%2e%2e/`, `..%2f`) | `__rel()` rejects paths containing `..` segments. |
|
|
146
|
+
| **Double-slash** (`///etc/passwd`) | `__rel()` rejects results that still start with `/` after `slice(1)`. |
|
|
147
|
+
| **Null byte** (`%00`, `\0`) | `__rel()` rejects paths containing null bytes before and after `decodeURIComponent`. |
|
|
148
|
+
| **Absolute path** (`/etc/passwd`) | `__rel()` returns `null` for paths not starting with `/`. |
|
|
149
|
+
| **SPA fallback** | Unknown paths → `index.html`, never a directory listing. |
|
|
150
|
+
| **`clientDir` escape** | `resolveOptions` throws at build time if `clientDir` resolves outside `outDir`. |
|
|
151
|
+
| **Hashed assets** | Files matching `[-.][0-9a-f]{8,}.ext` get `Cache-Control: public, max-age=31536000, immutable`. Other files are not cached by default. |
|
|
152
|
+
|
|
153
|
+
The generated `__asset` function uses `path.join` — not `path.resolve` — so a leading `/` in the relative path stays inside the asset root.
|
|
154
|
+
|
|
155
|
+
### Server actions (`*.server.ts`)
|
|
156
|
+
|
|
157
|
+
- `*.server.ts` code is **never bundled into the client**. Client imports are replaced with tacho stubs that POST `/_action`. The original source stays server-only.
|
|
158
|
+
- `/_action` is POST-only. Non-POST requests return `405`.
|
|
159
|
+
- Method dispatch uses `Object.hasOwn`, blocking `__proto__` / `constructor` walks.
|
|
160
|
+
- Unknown or missing content-types → `415`.
|
|
161
|
+
- Body size capped at 1 MB by default (enforced on the actual body, not just `Content-Length`).
|
|
162
|
+
- Batch requests capped at 20 items (both HTTP and WebSocket transports).
|
|
163
|
+
|
|
164
|
+
### Host header
|
|
165
|
+
|
|
166
|
+
The generated dev server constructs `request.url` from `req.headers.host`. This is standard HTTP/1.1 behavior (same as Express, Hono, Koa, Node http). If your `src/server.ts` reads `request.url` to construct redirects, validate the host yourself — the framework cannot distinguish a legitimate host header from a malicious one. In production, your reverse proxy handles this.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oxidejs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Vite/Rsbuild plugin. One build → dist/server.js + optional client. Server actions via *.server.ts.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"unplugin": "^3.3.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"tacho": "^0.4.
|
|
62
|
+
"tacho": "^0.4.2"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@rsbuild/core": "*",
|