shadok-ai 0.17.36 → 0.17.38

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 CHANGED
@@ -161,7 +161,10 @@ Enter to skip; you can add it later from the web UI).
161
161
  `http://localhost:PORT/…`, which your browser cannot reach when the agents run
162
162
  in a container or on a remote box. Paste that failed address under *Finish a
163
163
  sign-in* in the Secrets panel (`POST /oauth-relay`, web UI only): the cockpit
164
- opens it on the agents' machine. Loopback http addresses with a port only.
164
+ opens it on the agents' machine. Loopback http addresses with a port only,
165
+ and only a callback (`code=`, `state=` or `error=` in the query); the
166
+ cockpit's own ports and well-known local services (debuggers, Docker's API,
167
+ databases) are refused, and only the listener's HTTP status comes back.
165
168
  - **Scheduled prompts** — give a channel a recurring prompt (every N minutes, or
166
169
  daily at HH:MM in a time zone you choose) for monitoring and reporting. Each
167
170
  schedule can carry a **deterministic guard command** that runs *without the
@@ -254,6 +257,9 @@ Enter to skip; you can add it later from the web UI).
254
257
  with a command goes to the agent bare, without shadok's context line or
255
258
  ledger update ahead of it, since Claude Code reads a command only when `/`
256
259
  comes first.
260
+ The ✦ button beside the paperclip opens the same menu without typing, like
261
+ an emoji picker: the chosen skill goes in **front** of what you already
262
+ wrote (which becomes its argument), replacing a command already there.
257
263
  - **Files you hand an agent** — paste or drop a file into the composer, or pick
258
264
  one with the 📎 button beside it (an image, a PDF, a CSV…), and it becomes a **chip** above the text box: a
259
265
  thumbnail for an image, a named tag for anything else, each with a ✕ to
@@ -301,6 +307,14 @@ Enter to skip; you can add it later from the web UI).
301
307
  - **The detail panel.** Its numbers, where it runs (group by group: each
302
308
  agent, its schedule, its runs), the secrets agents running it get, and its
303
309
  feedback.
310
+ - **Creating.** The new-skill form asks for a **name** (what people see) and
311
+ a **technical name** (what agents call it, `/name:name`), proposed from the
312
+ name until you type your own. Choose it then: it is the skill's repository
313
+ and plugin name, so it cannot be changed afterwards. A name already taken
314
+ gets a number (`-2`, `-3`…), and the form says so before you create it.
315
+ - **Renaming.** Click a skill's name at the top of its editor to rename it
316
+ (Enter saves, Escape cancels). Only the displayed name changes: agents keep
317
+ calling it by its technical name, so attached agents are not disturbed.
304
318
  - **Sharing.** A skill is shared with **only me**, with **one or more
305
319
  groups**, or with **everyone**. Sharing keeps lists short; it is not a
306
320
  lock. "Only me" hides the skill from everyone else. A group skill is offered
@@ -694,6 +708,38 @@ the same-origin policy, so without that check any page you happen to visit could
694
708
  drive your agents. Behind a reverse proxy that rewrites `Host`, list the public
695
709
  origin in `SHADOK_ORIGINS`.
696
710
 
711
+ **Which host names it answers (DNS rebinding).** A page on `evil.com` can
712
+ re-point its own name at `127.0.0.1`; its requests then carry `Origin` *and*
713
+ `Host` `evil.com:3789` and look same-origin. So the server also checks the
714
+ `Host` header, on every request and on the WebSocket upgrade:
715
+
716
+ - **No password** (the local default): only `localhost` / `*.localhost`, any IP
717
+ address, and this machine's own name (`hostname`, `hostname.local`) are
718
+ answered, on any port. Anything else gets `403 host not allowed` and one log
719
+ line. If you really reach a password-less cockpit through another name (an
720
+ `/etc/hosts` alias, a same-host proxy), add it to `SHADOK_ALLOWED_HOSTS`.
721
+ - **With a password**: every `Host` is answered, as before — a rebound page
722
+ holds no cookie for your cockpit, so it is a stranger at the login page. This
723
+ is what keeps a container behind nginx/Cloudflare on its own domain working
724
+ with no change. Setting `SHADOK_ALLOWED_HOSTS` tightens it to that list
725
+ (loopback names and IPs always stay allowed — agents call `127.0.0.1`).
726
+
727
+ `SHADOK_ALLOWED_HOSTS` is comma-separated: names, `host:port` or whole origins
728
+ (the port is ignored), `.example.com` for a domain and its subdomains, `*` to
729
+ switch the check off. The hosts in `SHADOK_ORIGINS` are accepted too.
730
+
731
+ **Sign-in attempts are limited.** A failed `POST /login` is counted against the
732
+ caller's address (10 per 15 minutes) and against the account (20 per 15
733
+ minutes, from all addresses together); past that the answer is `429` with a
734
+ `Retry-After`, before any password is checked. Enrollment codes are counted the
735
+ same way. An unknown user name costs the server exactly what a real one does,
736
+ so the timing says nothing about which accounts exist. The counters live in
737
+ memory: a restart clears them. Behind a proxy the address is the one the proxy
738
+ appended last to `X-Forwarded-For` — trusted only when the proxy connects from
739
+ this machine or a private range (the Docker bridge); a proxy that sends no
740
+ `X-Forwarded-For` puts every visitor in one address bucket, so ten wrong
741
+ passwords from anyone lock the login for everyone for 15 minutes.
742
+
697
743
  ### Behind TLS (nginx, Caddy…)
698
744
 
699
745
  Serving the cockpit over HTTPS works, with one requirement: **the proxy must
@@ -710,6 +756,7 @@ location / {
710
756
  proxy_set_header Connection "upgrade";
711
757
  proxy_set_header Host $host;
712
758
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # see below
759
+ proxy_set_header X-Forwarded-Proto $scheme; # Secure cookies
713
760
  client_max_body_size 50m; # match the server's paste limit
714
761
  }
715
762
  ```
@@ -723,6 +770,14 @@ server the request was relayed. Without it, requests through a same-host proxy
723
770
  look local. (A proxy on another host, or nginx in front of a Docker container,
724
771
  is already seen as the network.)
725
772
 
773
+ The same header is what the sign-in limiter keys on (see "Exposing it beyond
774
+ this machine").
775
+
776
+ **Secure cookies.** With `X-Forwarded-Proto: https` from a proxy on this machine
777
+ or a private range (Docker bridge), the session cookies are set `Secure`, so a
778
+ browser never sends them over plain http. Without that header they are set as
779
+ before.
780
+
726
781
  The client picks `wss://` on its own when the page is HTTPS, so there is nothing
727
782
  to configure on that side.
728
783
 
@@ -936,7 +991,8 @@ machine, which silently shifts every daily prompt on a server running in UTC.
936
991
  | `PORT` | HTTP/WS port |
937
992
  | `SHADOK_HOST` | interface to bind (default `127.0.0.1`, this machine only) |
938
993
  | `SHADOK_GUI_PASSWORD` | require a password for the GUI — overrides a password saved by `--password` |
939
- | `SHADOK_ORIGINS` | extra browser origins allowed, comma-separated (reverse proxy) |
994
+ | `SHADOK_ORIGINS` | extra browser origins allowed, comma-separated (reverse proxy); their hosts also pass the Host check |
995
+ | `SHADOK_ALLOWED_HOSTS` | host names the cockpit answers besides its own (DNS-rebinding guard); with a password, setting it makes the check strict. `*` disables it |
940
996
  | `SHADOK_TMUX=0` | force the node-pty transport instead of tmux |
941
997
  | `SHADOK_IDLE_MIN` | minutes with no client before a session is reclaimed (60) |
942
998
  | `SHADOK_PERMISSION_MODE` | mode new agents start in (default `acceptEdits`) |
@@ -55,6 +55,19 @@ export declare function saveAccounts(list: Account[]): void;
55
55
  * not produce the same hash and cannot be spotted as identical. */
56
56
  export declare function hashPassword(plain: string): string;
57
57
  export declare function verifyPassword(plain: string, hash: string): boolean;
58
+ /**
59
+ * The async twins, for the request path. `scryptSync` runs ON the event loop:
60
+ * every sign-in attempt froze every agent's I/O for the length of a hash, and a
61
+ * guesser could hold the server down that way. `scrypt` runs on the libuv pool.
62
+ */
63
+ export declare function hashPasswordAsync(plain: string): Promise<string>;
64
+ export declare function verifyPasswordAsync(plain: string, hash: string): Promise<boolean>;
65
+ /**
66
+ * The check an UNKNOWN account (or an invitation not yet redeemed) gets: the
67
+ * same scrypt as a real one, always false. Answering such a name at once while
68
+ * a real one took a hash's time told a guesser which accounts exist.
69
+ */
70
+ export declare function burnPasswordCheck(plain: string): Promise<false>;
58
71
  /**
59
72
  * Who may change which account. Pure, so the whole policy is one testable
60
73
  * place rather than a condition repeated at three endpoints.
package/dist/accounts.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { createHmac, randomBytes, scryptSync, timingSafeEqual } from "node:crypto";
4
+ import { createHmac, randomBytes, scrypt, scryptSync, timingSafeEqual } from "node:crypto";
5
5
  import { instanceKey } from "./paths.js";
6
6
  /** The account that lives in SHADOK_GUI_PASSWORD, never in the file. */
7
7
  export const BOOTSTRAP_ADMIN = "admin";
@@ -46,6 +46,47 @@ export function verifyPassword(plain, hash) {
46
46
  return false;
47
47
  }
48
48
  }
49
+ function scryptAsync(plain, salt, len) {
50
+ return new Promise((resolve, reject) => scrypt(plain, salt, len, (err, key) => (err ? reject(err) : resolve(key))));
51
+ }
52
+ /**
53
+ * The async twins, for the request path. `scryptSync` runs ON the event loop:
54
+ * every sign-in attempt froze every agent's I/O for the length of a hash, and a
55
+ * guesser could hold the server down that way. `scrypt` runs on the libuv pool.
56
+ */
57
+ export async function hashPasswordAsync(plain) {
58
+ const salt = randomBytes(16);
59
+ const key = await scryptAsync(plain, salt, 64);
60
+ return `scrypt$${salt.toString("hex")}$${key.toString("hex")}`;
61
+ }
62
+ export async function verifyPasswordAsync(plain, hash) {
63
+ const parts = String(hash ?? "").split("$");
64
+ if (parts.length !== 3 || parts[0] !== "scrypt")
65
+ return false;
66
+ try {
67
+ const salt = Buffer.from(parts[1], "hex");
68
+ const want = Buffer.from(parts[2], "hex");
69
+ if (!salt.length || !want.length)
70
+ return false;
71
+ const got = await scryptAsync(plain, salt, want.length);
72
+ return got.length === want.length && timingSafeEqual(got, want);
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ /** A hash no password matches (the derived half is all zeros), same shape and
79
+ * cost as a real one. */
80
+ const DUMMY_HASH = `scrypt$${"5a".repeat(16)}$${"00".repeat(64)}`;
81
+ /**
82
+ * The check an UNKNOWN account (or an invitation not yet redeemed) gets: the
83
+ * same scrypt as a real one, always false. Answering such a name at once while
84
+ * a real one took a hash's time told a guesser which accounts exist.
85
+ */
86
+ export async function burnPasswordCheck(plain) {
87
+ await verifyPasswordAsync(plain, DUMMY_HASH);
88
+ return false;
89
+ }
49
90
  /**
50
91
  * Who may change which account. Pure, so the whole policy is one testable
51
92
  * place rather than a condition repeated at three endpoints.
@@ -1 +1 @@
1
- {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../src/accounts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../src/accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Failed sign-in attempts, counted per address AND per account, in memory.
3
+ *
4
+ * `POST /login` used to accept guesses as fast as they came: with a password
5
+ * set, the password is the door to a shell on the host, and nothing slowed a
6
+ * guesser down. Two buckets, because each alone fails: per address alone lets
7
+ * a guesser rotating addresses hammer one account; per account alone lets one
8
+ * guesser lock every named user out. The account bucket is therefore the larger
9
+ * one — it caps a distributed attack without making a lockout of someone else
10
+ * cheap.
11
+ *
12
+ * A blocked attempt is refused BEFORE the hash is computed: a flood costs the
13
+ * server nothing past the limit. Memory is bounded (`maxKeys`) because the
14
+ * account key is whatever name the guesser typed. A restart forgets everything,
15
+ * deliberately — a limiter that could lock the owner out across restarts would
16
+ * be worse than one a restart resets. Pure over an injected clock — tested.
17
+ */
18
+ export type LimitConfig = {
19
+ windowMs: number;
20
+ maxPerIp: number;
21
+ maxPerAccount: number;
22
+ maxKeys?: number;
23
+ };
24
+ export declare const LOGIN_LIMITS: LimitConfig;
25
+ export type LimitVerdict = {
26
+ ok: true;
27
+ } | {
28
+ ok: false;
29
+ retryAfterMs: number;
30
+ };
31
+ /** The buckets one attempt is charged to. A blank user IS the admin. */
32
+ export declare function loginKeys(address: string, user: string): string[];
33
+ export declare class AttemptLimiter {
34
+ private cfg;
35
+ private now;
36
+ private failures;
37
+ constructor(cfg: LimitConfig, now?: () => number);
38
+ private live;
39
+ private max;
40
+ check(keys: string[]): LimitVerdict;
41
+ fail(keys: string[]): void;
42
+ /** A correct password clears the ACCOUNT's failures (whoever caused them),
43
+ * never the address's: a guesser holding one valid account must not be able
44
+ * to reset their own address bucket between guesses at another. */
45
+ succeed(keys: string[]): void;
46
+ size(): number;
47
+ private bound;
48
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Failed sign-in attempts, counted per address AND per account, in memory.
3
+ *
4
+ * `POST /login` used to accept guesses as fast as they came: with a password
5
+ * set, the password is the door to a shell on the host, and nothing slowed a
6
+ * guesser down. Two buckets, because each alone fails: per address alone lets
7
+ * a guesser rotating addresses hammer one account; per account alone lets one
8
+ * guesser lock every named user out. The account bucket is therefore the larger
9
+ * one — it caps a distributed attack without making a lockout of someone else
10
+ * cheap.
11
+ *
12
+ * A blocked attempt is refused BEFORE the hash is computed: a flood costs the
13
+ * server nothing past the limit. Memory is bounded (`maxKeys`) because the
14
+ * account key is whatever name the guesser typed. A restart forgets everything,
15
+ * deliberately — a limiter that could lock the owner out across restarts would
16
+ * be worse than one a restart resets. Pure over an injected clock — tested.
17
+ */
18
+ export const LOGIN_LIMITS = {
19
+ windowMs: 15 * 60_000,
20
+ maxPerIp: 10,
21
+ maxPerAccount: 20,
22
+ maxKeys: 10_000,
23
+ };
24
+ /** The buckets one attempt is charged to. A blank user IS the admin. */
25
+ export function loginKeys(address, user) {
26
+ return [`ip:${address}`, `acct:${user || "admin"}`];
27
+ }
28
+ export class AttemptLimiter {
29
+ cfg;
30
+ now;
31
+ failures = new Map();
32
+ constructor(cfg, now = Date.now) {
33
+ this.cfg = cfg;
34
+ this.now = now;
35
+ }
36
+ live(key) {
37
+ const cut = this.now() - this.cfg.windowMs;
38
+ const kept = (this.failures.get(key) ?? []).filter((t) => t > cut);
39
+ if (kept.length)
40
+ this.failures.set(key, kept);
41
+ else
42
+ this.failures.delete(key);
43
+ return kept;
44
+ }
45
+ max(key) {
46
+ return key.startsWith("ip:") ? this.cfg.maxPerIp : this.cfg.maxPerAccount;
47
+ }
48
+ check(keys) {
49
+ let wait = 0;
50
+ for (const k of keys) {
51
+ const f = this.live(k);
52
+ const max = this.max(k);
53
+ if (f.length >= max)
54
+ wait = Math.max(wait, f[f.length - max] + this.cfg.windowMs - this.now());
55
+ }
56
+ return wait > 0 ? { ok: false, retryAfterMs: wait } : { ok: true };
57
+ }
58
+ fail(keys) {
59
+ const t = this.now();
60
+ for (const k of keys) {
61
+ const f = this.live(k);
62
+ f.push(t);
63
+ // Re-inserted at the end, so Map order is "least recently failed first".
64
+ this.failures.delete(k);
65
+ this.failures.set(k, f.slice(-this.max(k)));
66
+ }
67
+ this.bound();
68
+ }
69
+ /** A correct password clears the ACCOUNT's failures (whoever caused them),
70
+ * never the address's: a guesser holding one valid account must not be able
71
+ * to reset their own address bucket between guesses at another. */
72
+ succeed(keys) {
73
+ for (const k of keys)
74
+ if (!k.startsWith("ip:"))
75
+ this.failures.delete(k);
76
+ }
77
+ size() {
78
+ return this.failures.size;
79
+ }
80
+ bound() {
81
+ const cap = this.cfg.maxKeys ?? Infinity;
82
+ if (this.failures.size <= cap)
83
+ return;
84
+ for (const k of [...this.failures.keys()])
85
+ this.live(k);
86
+ while (this.failures.size > cap)
87
+ this.failures.delete(this.failures.keys().next().value);
88
+ }
89
+ }
90
+ //# sourceMappingURL=login-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-limit.js","sourceRoot":"","sources":["../src/login-limit.ts"],"names":[],"mappings":"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"}
package/dist/net.d.ts CHANGED
@@ -89,3 +89,61 @@ export declare function browserOrigin(origin: string | undefined, host: string |
89
89
  * Pure — unit tested.
90
90
  */
91
91
  export declare function isLocalCaller(remoteAddress: string | undefined, headers: Record<string, unknown>): boolean;
92
+ /**
93
+ * The hostname a `Host` header names, lowercased, port and IPv6 brackets
94
+ * stripped — or null when it is not a plain host (spaces, userinfo, a path).
95
+ */
96
+ export declare function hostNameOf(host: string): string | null;
97
+ /**
98
+ * `SHADOK_ALLOWED_HOSTS` (or the hosts of `SHADOK_ORIGINS`): comma-separated
99
+ * names, `host:port`, or whole origins — reduced to the bare hostname. A
100
+ * leading dot (`.example.com`) also matches every subdomain; `*` disables the
101
+ * check altogether.
102
+ */
103
+ export declare function parseAllowedHosts(raw: string | undefined): string[];
104
+ export type HostPolicy = {
105
+ /** A GUI password is set: a rebinding page gets no cookie, so it gets nothing. */
106
+ passwordSet: boolean;
107
+ /** `SHADOK_ALLOWED_HOSTS` — setting it ALSO turns the strict check on under a password. */
108
+ allowedHosts: string[];
109
+ /** Hosts of `SHADOK_ORIGINS` — accepted, but they never turn strictness on. */
110
+ originHosts: string[];
111
+ /** This machine's own name(s) (`os.hostname()`): no attacker can serve a page on it. */
112
+ machineNames: string[];
113
+ };
114
+ /**
115
+ * May a request naming this `Host` be served? The defence against DNS
116
+ * rebinding, which `originAllowed` cannot provide: a page on `evil.com` that
117
+ * re-points its own name at 127.0.0.1 sends `Origin: http://evil.com:3789` AND
118
+ * `Host: evil.com:3789` — same-origin by every measure — and, with no password
119
+ * (the local default, where everything is the admin), drives the agents.
120
+ *
121
+ * Rebinding only ever produces a DOMAIN NAME the attacker controls, so the
122
+ * strict rule accepts what such a page cannot be: an IP literal (a browser on
123
+ * an IP sends that IP), `localhost` and `*.localhost` (resolved to loopback by
124
+ * the browser itself, RFC 6761), this machine's own name, and the lists.
125
+ *
126
+ * Strict only when it is NEEDED, so no deployment that exists today breaks:
127
+ * with a password the cookie is bound to the attacker's origin and a rebound
128
+ * page is just an unauthenticated stranger — every Host passes, as before,
129
+ * unless `SHADOK_ALLOWED_HOSTS` asks to tighten. A missing Host is a
130
+ * non-browser client (browsers always send one) and passes, like a missing
131
+ * Origin (invariant 11). Pure — unit tested.
132
+ */
133
+ export declare function hostHeaderAllowed(host: string | undefined, p: HostPolicy): boolean;
134
+ /** What a refused Host is told — names the knob, since a lockout must be fixable. */
135
+ export declare function hostRefusal(host: string): string;
136
+ /**
137
+ * The address a login attempt is charged to. The socket's, unless the socket is
138
+ * a trusted hop (loopback, or a private range — the Docker bridge an nginx on
139
+ * the host connects from) carrying `X-Forwarded-For`: then the LAST entry,
140
+ * the one OUR proxy appended (`$proxy_add_x_forwarded_for`). Everything before
141
+ * it is whatever the client claimed and is never trusted. Pure — unit tested.
142
+ */
143
+ export declare function clientAddress(remoteAddress: string | undefined, headers: Record<string, unknown>): string;
144
+ /**
145
+ * Did the browser reach us over HTTPS? A TLS socket, or a trusted hop saying
146
+ * so in `X-Forwarded-Proto` (first value: the outermost proxy's). Decides the
147
+ * cookies' `Secure` flag. Pure — unit tested.
148
+ */
149
+ export declare function requestIsHttps(encrypted: boolean, remoteAddress: string | undefined, headers: Record<string, unknown>): boolean;
package/dist/net.js CHANGED
@@ -137,4 +137,153 @@ export function isLocalCaller(remoteAddress, headers) {
137
137
  return false;
138
138
  return !["forwarded", "x-forwarded-for", "x-real-ip", "x-forwarded-host"].some((h) => headers[h] !== undefined);
139
139
  }
140
+ // ── DNS rebinding: the Host allowlist ─────────────────────────────────────
141
+ /**
142
+ * The hostname a `Host` header names, lowercased, port and IPv6 brackets
143
+ * stripped — or null when it is not a plain host (spaces, userinfo, a path).
144
+ */
145
+ export function hostNameOf(host) {
146
+ const h = host.trim().toLowerCase();
147
+ if (!h)
148
+ return null;
149
+ const v6 = /^\[([0-9a-f:.]+)\](?::\d{1,5})?$/.exec(h);
150
+ if (v6)
151
+ return v6[1];
152
+ const m = /^([a-z0-9._-]+)(?::\d{1,5})?$/.exec(h);
153
+ return m ? m[1].replace(/\.$/, "") : null;
154
+ }
155
+ /** An IPv4 or IPv6 literal (as `hostNameOf` returns it). */
156
+ function isIpLiteral(name) {
157
+ return /^\d{1,3}(\.\d{1,3}){3}$/.test(name) || (name.includes(":") && /^[0-9a-f:.]+$/.test(name));
158
+ }
159
+ /**
160
+ * `SHADOK_ALLOWED_HOSTS` (or the hosts of `SHADOK_ORIGINS`): comma-separated
161
+ * names, `host:port`, or whole origins — reduced to the bare hostname. A
162
+ * leading dot (`.example.com`) also matches every subdomain; `*` disables the
163
+ * check altogether.
164
+ */
165
+ export function parseAllowedHosts(raw) {
166
+ const out = [];
167
+ for (const part of (raw ?? "").split(",")) {
168
+ const s = part.trim().toLowerCase();
169
+ if (!s)
170
+ continue;
171
+ if (s === "*") {
172
+ out.push("*");
173
+ continue;
174
+ }
175
+ if (s.startsWith(".")) {
176
+ const n = hostNameOf(s.slice(1));
177
+ if (n)
178
+ out.push("." + n);
179
+ continue;
180
+ }
181
+ let n = null;
182
+ if (s.includes("://")) {
183
+ try {
184
+ n = hostNameOf(new URL(s).host);
185
+ }
186
+ catch {
187
+ n = null;
188
+ }
189
+ }
190
+ else
191
+ n = hostNameOf(s.replace(/\/+$/, ""));
192
+ if (n)
193
+ out.push(n);
194
+ }
195
+ return out;
196
+ }
197
+ function listed(name, list) {
198
+ return list.some((e) => (e.startsWith(".") ? name === e.slice(1) || name.endsWith(e) : name === e));
199
+ }
200
+ /**
201
+ * May a request naming this `Host` be served? The defence against DNS
202
+ * rebinding, which `originAllowed` cannot provide: a page on `evil.com` that
203
+ * re-points its own name at 127.0.0.1 sends `Origin: http://evil.com:3789` AND
204
+ * `Host: evil.com:3789` — same-origin by every measure — and, with no password
205
+ * (the local default, where everything is the admin), drives the agents.
206
+ *
207
+ * Rebinding only ever produces a DOMAIN NAME the attacker controls, so the
208
+ * strict rule accepts what such a page cannot be: an IP literal (a browser on
209
+ * an IP sends that IP), `localhost` and `*.localhost` (resolved to loopback by
210
+ * the browser itself, RFC 6761), this machine's own name, and the lists.
211
+ *
212
+ * Strict only when it is NEEDED, so no deployment that exists today breaks:
213
+ * with a password the cookie is bound to the attacker's origin and a rebound
214
+ * page is just an unauthenticated stranger — every Host passes, as before,
215
+ * unless `SHADOK_ALLOWED_HOSTS` asks to tighten. A missing Host is a
216
+ * non-browser client (browsers always send one) and passes, like a missing
217
+ * Origin (invariant 11). Pure — unit tested.
218
+ */
219
+ export function hostHeaderAllowed(host, p) {
220
+ if (p.allowedHosts.includes("*"))
221
+ return true;
222
+ if (!host || !host.trim())
223
+ return true;
224
+ const strict = !p.passwordSet || p.allowedHosts.length > 0;
225
+ if (!strict)
226
+ return true;
227
+ const name = hostNameOf(host);
228
+ if (!name)
229
+ return false;
230
+ if (isIpLiteral(name))
231
+ return true;
232
+ if (name === "localhost" || name.endsWith(".localhost"))
233
+ return true;
234
+ if (p.machineNames.some((m) => m && (name === m || name === `${m}.local`)))
235
+ return true;
236
+ return listed(name, p.allowedHosts) || listed(name, p.originHosts);
237
+ }
238
+ /** What a refused Host is told — names the knob, since a lockout must be fixable. */
239
+ export function hostRefusal(host) {
240
+ const name = hostNameOf(host) ?? host;
241
+ return (`host not allowed: ${name}. The cockpit only answers its own names (DNS-rebinding protection). ` +
242
+ `If this is really how you reach it, add it to SHADOK_ALLOWED_HOSTS (comma-separated) and restart.`);
243
+ }
244
+ // ── Who is calling, through a proxy we trust ──────────────────────────────
245
+ /** Loopback or a private range: a hop on this machine or its container bridge. */
246
+ function isTrustedHop(remote) {
247
+ const a = remote.toLowerCase().replace(/^::ffff:/, "");
248
+ if (a === "::1" || a.startsWith("127."))
249
+ return true;
250
+ if (/^10\./.test(a) || /^192\.168\./.test(a))
251
+ return true;
252
+ const m = /^172\.(\d+)\./.exec(a);
253
+ if (m && +m[1] >= 16 && +m[1] <= 31)
254
+ return true;
255
+ return /^f[cd][0-9a-f]{2}:/.test(a);
256
+ }
257
+ function firstHeader(v) {
258
+ return Array.isArray(v) ? String(v[0] ?? "") : typeof v === "string" ? v : "";
259
+ }
260
+ /**
261
+ * The address a login attempt is charged to. The socket's, unless the socket is
262
+ * a trusted hop (loopback, or a private range — the Docker bridge an nginx on
263
+ * the host connects from) carrying `X-Forwarded-For`: then the LAST entry,
264
+ * the one OUR proxy appended (`$proxy_add_x_forwarded_for`). Everything before
265
+ * it is whatever the client claimed and is never trusted. Pure — unit tested.
266
+ */
267
+ export function clientAddress(remoteAddress, headers) {
268
+ if (!remoteAddress)
269
+ return "unknown";
270
+ const direct = remoteAddress.toLowerCase().replace(/^::ffff:/, "");
271
+ const xff = firstHeader(headers["x-forwarded-for"]);
272
+ if (!xff || !isTrustedHop(remoteAddress))
273
+ return direct;
274
+ const last = xff.split(",").map((s) => s.trim()).filter(Boolean).pop();
275
+ return last ? last.toLowerCase().replace(/^::ffff:/, "") : direct;
276
+ }
277
+ /**
278
+ * Did the browser reach us over HTTPS? A TLS socket, or a trusted hop saying
279
+ * so in `X-Forwarded-Proto` (first value: the outermost proxy's). Decides the
280
+ * cookies' `Secure` flag. Pure — unit tested.
281
+ */
282
+ export function requestIsHttps(encrypted, remoteAddress, headers) {
283
+ if (encrypted)
284
+ return true;
285
+ if (!remoteAddress || !isTrustedHop(remoteAddress))
286
+ return false;
287
+ return firstHeader(headers["x-forwarded-proto"]).split(",")[0].trim().toLowerCase() === "https";
288
+ }
140
289
  //# sourceMappingURL=net.js.map
package/dist/net.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"net.js","sourceRoot":"","sources":["../src/net.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"net.js","sourceRoot":"","sources":["../src/net.ts"],"names":[],"mappings":"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"}