shadok-ai 0.17.37 → 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 +47 -2
- package/dist/accounts.d.ts +13 -0
- package/dist/accounts.js +42 -1
- package/dist/accounts.js.map +1 -1
- package/dist/login-limit.d.ts +48 -0
- package/dist/login-limit.js +90 -0
- package/dist/login-limit.js.map +1 -0
- package/dist/net.d.ts +58 -0
- package/dist/net.js +149 -0
- package/dist/net.js.map +1 -1
- package/dist/oauth-relay.d.ts +15 -5
- package/dist/oauth-relay.js +29 -9
- package/dist/oauth-relay.js.map +1 -1
- package/dist/server.js +106 -32
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +4 -1
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
|
|
@@ -705,6 +708,38 @@ the same-origin policy, so without that check any page you happen to visit could
|
|
|
705
708
|
drive your agents. Behind a reverse proxy that rewrites `Host`, list the public
|
|
706
709
|
origin in `SHADOK_ORIGINS`.
|
|
707
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
|
+
|
|
708
743
|
### Behind TLS (nginx, Caddy…)
|
|
709
744
|
|
|
710
745
|
Serving the cockpit over HTTPS works, with one requirement: **the proxy must
|
|
@@ -721,6 +756,7 @@ location / {
|
|
|
721
756
|
proxy_set_header Connection "upgrade";
|
|
722
757
|
proxy_set_header Host $host;
|
|
723
758
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # see below
|
|
759
|
+
proxy_set_header X-Forwarded-Proto $scheme; # Secure cookies
|
|
724
760
|
client_max_body_size 50m; # match the server's paste limit
|
|
725
761
|
}
|
|
726
762
|
```
|
|
@@ -734,6 +770,14 @@ server the request was relayed. Without it, requests through a same-host proxy
|
|
|
734
770
|
look local. (A proxy on another host, or nginx in front of a Docker container,
|
|
735
771
|
is already seen as the network.)
|
|
736
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
|
+
|
|
737
781
|
The client picks `wss://` on its own when the page is HTTPS, so there is nothing
|
|
738
782
|
to configure on that side.
|
|
739
783
|
|
|
@@ -947,7 +991,8 @@ machine, which silently shifts every daily prompt on a server running in UTC.
|
|
|
947
991
|
| `PORT` | HTTP/WS port |
|
|
948
992
|
| `SHADOK_HOST` | interface to bind (default `127.0.0.1`, this machine only) |
|
|
949
993
|
| `SHADOK_GUI_PASSWORD` | require a password for the GUI — overrides a password saved by `--password` |
|
|
950
|
-
| `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 |
|
|
951
996
|
| `SHADOK_TMUX=0` | force the node-pty transport instead of tmux |
|
|
952
997
|
| `SHADOK_IDLE_MIN` | minutes with no client before a session is reclaimed (60) |
|
|
953
998
|
| `SHADOK_PERMISSION_MODE` | mode new agents start in (default `acceptEdits`) |
|
package/dist/accounts.d.ts
CHANGED
|
@@ -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.
|
package/dist/accounts.js.map
CHANGED
|
@@ -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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"}
|
package/dist/oauth-relay.d.ts
CHANGED
|
@@ -10,8 +10,15 @@
|
|
|
10
10
|
* load and pastes it in the web UI; the cockpit, which IS on the agents'
|
|
11
11
|
* machine, opens it for them.
|
|
12
12
|
*
|
|
13
|
-
* Loopback only, http only, explicit port
|
|
14
|
-
*
|
|
13
|
+
* Loopback only, http only, explicit port, and the address must LOOK like an
|
|
14
|
+
* OAuth callback (a `code`, `state` or `error` parameter): this relays a
|
|
15
|
+
* callback, it is not a general fetch — anything else is refused before a
|
|
16
|
+
* socket is opened. The cockpit sits where the agents sit, so a relay that took
|
|
17
|
+
* any path on any port was a way for whoever reaches the cockpit to read the
|
|
18
|
+
* machine's local services (a debugger on 9222/9229, a Docker API on 2375,
|
|
19
|
+
* another cockpit). Those ports are refused outright, and the reply carries the
|
|
20
|
+
* listener's STATUS only, never its body — the body is what turned a probe into
|
|
21
|
+
* a read.
|
|
15
22
|
*/
|
|
16
23
|
export type RelayTarget = {
|
|
17
24
|
ok: true;
|
|
@@ -23,11 +30,14 @@ export type RelayTarget = {
|
|
|
23
30
|
export type RelayResult = {
|
|
24
31
|
ok: true;
|
|
25
32
|
status: number;
|
|
26
|
-
text: string;
|
|
27
33
|
} | {
|
|
28
34
|
ok: false;
|
|
29
35
|
error: string;
|
|
30
36
|
};
|
|
31
|
-
export declare function relayTarget(raw: unknown
|
|
37
|
+
export declare function relayTarget(raw: unknown, opts?: {
|
|
38
|
+
ownPort?: number;
|
|
39
|
+
}): RelayTarget;
|
|
32
40
|
/** GET the callback where the agent listens; report what the listener said. */
|
|
33
|
-
export declare function relayOAuthCallback(raw: unknown, timeoutMs?: number
|
|
41
|
+
export declare function relayOAuthCallback(raw: unknown, timeoutMs?: number, opts?: {
|
|
42
|
+
ownPort?: number;
|
|
43
|
+
}): Promise<RelayResult>;
|