@namzu/sandbox 2.0.3 → 3.0.0
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/CHANGELOG.md +55 -0
- package/README.md +62 -1
- package/dist/backends/docker/index.d.ts +26 -1
- package/dist/backends/docker/index.d.ts.map +1 -1
- package/dist/backends/docker/index.js +20 -7
- package/dist/backends/docker/index.js.map +1 -1
- package/dist/egress/address.d.ts +75 -0
- package/dist/egress/address.d.ts.map +1 -0
- package/dist/egress/address.js +289 -0
- package/dist/egress/address.js.map +1 -0
- package/dist/egress/index.d.ts +2 -0
- package/dist/egress/index.d.ts.map +1 -1
- package/dist/egress/index.js +1 -0
- package/dist/egress/index.js.map +1 -1
- package/dist/egress/proxy.d.ts +41 -0
- package/dist/egress/proxy.d.ts.map +1 -1
- package/dist/egress/proxy.js +83 -2
- package/dist/egress/proxy.js.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/backends/docker/index.ts +45 -8
- package/src/egress/address.ts +366 -0
- package/src/egress/index.ts +7 -0
- package/src/egress/proxy.ts +106 -2
- package/src/index.ts +18 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { lookup as dnsLookup } from 'node:dns';
|
|
2
|
+
import { isIP } from 'node:net';
|
|
3
|
+
const V4_RANGES = [
|
|
4
|
+
{ reason: 'loopback', matches: (o) => o[0] === 127 },
|
|
5
|
+
{ reason: 'this-host', matches: (o) => o[0] === 0 },
|
|
6
|
+
{ reason: 'private', matches: (o) => o[0] === 10 },
|
|
7
|
+
{ reason: 'private', matches: (o) => o[0] === 172 && (o[1] ?? 0) >= 16 && (o[1] ?? 0) <= 31 },
|
|
8
|
+
{ reason: 'private', matches: (o) => o[0] === 192 && o[1] === 168 },
|
|
9
|
+
// 169.254.0.0/16. The metadata address every major host platform answers
|
|
10
|
+
// on lives here, which is why this range is the one that turns a name
|
|
11
|
+
// check into a credential leak.
|
|
12
|
+
{ reason: 'link-local', matches: (o) => o[0] === 169 && o[1] === 254 },
|
|
13
|
+
{
|
|
14
|
+
reason: 'shared-address-space',
|
|
15
|
+
matches: (o) => o[0] === 100 && (o[1] ?? 0) >= 64 && (o[1] ?? 0) <= 127,
|
|
16
|
+
},
|
|
17
|
+
{ reason: 'benchmarking', matches: (o) => o[0] === 198 && (o[1] === 18 || o[1] === 19) },
|
|
18
|
+
{ reason: 'multicast', matches: (o) => (o[0] ?? 0) >= 224 && (o[0] ?? 0) <= 239 },
|
|
19
|
+
{ reason: 'reserved', matches: (o) => (o[0] ?? 0) >= 240 },
|
|
20
|
+
];
|
|
21
|
+
function parseV4(address) {
|
|
22
|
+
const parts = address.split('.');
|
|
23
|
+
if (parts.length !== 4)
|
|
24
|
+
return null;
|
|
25
|
+
const octets = [];
|
|
26
|
+
for (const part of parts) {
|
|
27
|
+
if (!/^\d{1,3}$/.test(part))
|
|
28
|
+
return null;
|
|
29
|
+
const n = Number(part);
|
|
30
|
+
if (n > 255)
|
|
31
|
+
return null;
|
|
32
|
+
octets.push(n);
|
|
33
|
+
}
|
|
34
|
+
return octets;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Expand an IPv6 literal into its eight 16-bit groups, or `null`.
|
|
38
|
+
*
|
|
39
|
+
* Written out rather than pattern-matched on the text, because a prefix
|
|
40
|
+
* matched as a STRING is a different question from a prefix matched as a
|
|
41
|
+
* NUMBER, and the two disagree exactly where it hurts. `/^f[cd]/` was the
|
|
42
|
+
* first spelling of the unique-local check here, and `fd::1` matches it —
|
|
43
|
+
* but `fd::1` is `00fd:0:…`, an ordinary global address, so that check
|
|
44
|
+
* deleted a slice of the internet. `fe8::1` did the same against
|
|
45
|
+
* `/^fe[89ab]/`. Both are the `>=`-where-`>`-was-meant mistake wearing a
|
|
46
|
+
* regex.
|
|
47
|
+
*
|
|
48
|
+
* It fails the other way too. `0:0:0:0:0:ffff:169.254.169.254` is the
|
|
49
|
+
* metadata address written long, and no `^::`-anchored pattern sees it.
|
|
50
|
+
*/
|
|
51
|
+
function parseV6(address) {
|
|
52
|
+
// A zone id (`%eth0`) names an interface, not a different address.
|
|
53
|
+
const text = (address.toLowerCase().split('%')[0] ?? '').trim();
|
|
54
|
+
if (text.length === 0)
|
|
55
|
+
return null;
|
|
56
|
+
// A trailing dotted quad is the last two groups written in v4 notation.
|
|
57
|
+
let head = text;
|
|
58
|
+
let tail = [];
|
|
59
|
+
const lastColon = text.lastIndexOf(':');
|
|
60
|
+
const after = lastColon >= 0 ? text.slice(lastColon + 1) : '';
|
|
61
|
+
if (after.includes('.')) {
|
|
62
|
+
const quad = parseV4(after);
|
|
63
|
+
if (!quad)
|
|
64
|
+
return null;
|
|
65
|
+
const [a, b, c, d] = quad;
|
|
66
|
+
tail = [(a << 8) | b, (c << 8) | d];
|
|
67
|
+
head = text.slice(0, lastColon + 1);
|
|
68
|
+
if (head.endsWith(':') && !head.endsWith('::'))
|
|
69
|
+
head = head.slice(0, -1);
|
|
70
|
+
}
|
|
71
|
+
const halves = head.split('::');
|
|
72
|
+
if (halves.length > 2)
|
|
73
|
+
return null;
|
|
74
|
+
const toGroups = (part) => {
|
|
75
|
+
if (part.length === 0)
|
|
76
|
+
return [];
|
|
77
|
+
const out = [];
|
|
78
|
+
for (const piece of part.split(':')) {
|
|
79
|
+
if (!/^[0-9a-f]{1,4}$/.test(piece))
|
|
80
|
+
return null;
|
|
81
|
+
out.push(Number.parseInt(piece, 16));
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
};
|
|
85
|
+
if (halves.length === 1) {
|
|
86
|
+
const only = toGroups(halves[0] ?? '');
|
|
87
|
+
if (!only)
|
|
88
|
+
return null;
|
|
89
|
+
const groups = [...only, ...tail];
|
|
90
|
+
return groups.length === 8 ? groups : null;
|
|
91
|
+
}
|
|
92
|
+
const left = toGroups(halves[0] ?? '');
|
|
93
|
+
const right = toGroups(halves[1] ?? '');
|
|
94
|
+
if (!left || !right)
|
|
95
|
+
return null;
|
|
96
|
+
const known = left.length + right.length + tail.length;
|
|
97
|
+
if (known > 8)
|
|
98
|
+
return null;
|
|
99
|
+
return [...left, ...new Array(8 - known).fill(0), ...right, ...tail];
|
|
100
|
+
}
|
|
101
|
+
/** Whether the first `count` groups are all zero. */
|
|
102
|
+
function zeroPrefix(groups, count) {
|
|
103
|
+
return groups.slice(0, count).every((g) => g === 0);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Why this address must not be reached, or `null` if it may be.
|
|
107
|
+
*
|
|
108
|
+
* Returns a reason rather than a boolean because the reason is what a
|
|
109
|
+
* denied operator needs: "link-local" and "private" are different mistakes
|
|
110
|
+
* with different fixes, and a bare `false` sends them to read this file.
|
|
111
|
+
*/
|
|
112
|
+
export function blockedAddressReason(address) {
|
|
113
|
+
const literal = unbracket(address);
|
|
114
|
+
const v4 = parseV4(literal);
|
|
115
|
+
if (v4) {
|
|
116
|
+
for (const range of V4_RANGES) {
|
|
117
|
+
if (range.matches(v4))
|
|
118
|
+
return range.reason;
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const groups = parseV6(literal);
|
|
123
|
+
if (!groups)
|
|
124
|
+
return null;
|
|
125
|
+
// `::ffff:a.b.c.d` (v4-mapped) and the deprecated `::a.b.c.d`
|
|
126
|
+
// (v4-compatible) are both the v4 address wearing a v6 spelling, and both
|
|
127
|
+
// reach the v4 host. A screen that only understands dotted quads passes
|
|
128
|
+
// them, which is a documented way through this kind of filter rather than
|
|
129
|
+
// an oversight worth ignoring.
|
|
130
|
+
if (zeroPrefix(groups, 5) && groups[5] === 0xffff) {
|
|
131
|
+
return blockedAddressReason(v4FromGroups(groups));
|
|
132
|
+
}
|
|
133
|
+
if (zeroPrefix(groups, 6) && !(groups[6] === 0 && (groups[7] ?? 0) <= 1)) {
|
|
134
|
+
return blockedAddressReason(v4FromGroups(groups));
|
|
135
|
+
}
|
|
136
|
+
if (zeroPrefix(groups, 7)) {
|
|
137
|
+
if (groups[7] === 1)
|
|
138
|
+
return 'loopback';
|
|
139
|
+
if (groups[7] === 0)
|
|
140
|
+
return 'unspecified';
|
|
141
|
+
}
|
|
142
|
+
const first = groups[0] ?? 0;
|
|
143
|
+
// Masked, not prefix-matched: fc00::/7, fe80::/10, ff00::/8.
|
|
144
|
+
if ((first & 0xfe00) === 0xfc00)
|
|
145
|
+
return 'unique-local';
|
|
146
|
+
if ((first & 0xffc0) === 0xfe80)
|
|
147
|
+
return 'link-local';
|
|
148
|
+
if ((first & 0xff00) === 0xff00)
|
|
149
|
+
return 'multicast';
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function v4FromGroups(groups) {
|
|
153
|
+
const high = groups[6] ?? 0;
|
|
154
|
+
const low = groups[7] ?? 0;
|
|
155
|
+
return `${high >> 8}.${high & 0xff}.${low >> 8}.${low & 0xff}`;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* An IPv6 literal arrives bracketed from one of the two paths.
|
|
159
|
+
*
|
|
160
|
+
* `new URL('http://[::1]/').hostname` is `[::1]`, brackets included, and
|
|
161
|
+
* `parseTarget` reads exactly that. The `Host`-header path hands the same
|
|
162
|
+
* address over bare, because `splitAuthority` strips the brackets itself —
|
|
163
|
+
* two spellings of one address, normalised here rather than at either call
|
|
164
|
+
* site.
|
|
165
|
+
*
|
|
166
|
+
* This is a layer, not a hole closed, and the difference was measured rather
|
|
167
|
+
* than assumed: Node does not read a bracketed string as an IP literal
|
|
168
|
+
* either, so without this the host falls through to `dns.lookup` and the
|
|
169
|
+
* screening resolver refuses it there. What this buys is that
|
|
170
|
+
* `blockedLiteralReason` stops answering `null` about an address it plainly
|
|
171
|
+
* recognises — a true-looking answer the next caller would build on.
|
|
172
|
+
*/
|
|
173
|
+
function unbracket(host) {
|
|
174
|
+
const trimmed = host.trim();
|
|
175
|
+
return trimmed.startsWith('[') && trimmed.endsWith(']') ? trimmed.slice(1, -1) : trimmed;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Screen a target that is already an address rather than a name.
|
|
179
|
+
*
|
|
180
|
+
* A `lookup` hook cannot cover this case and it is not obvious why: the
|
|
181
|
+
* socket layer skips resolution entirely when the host is a valid IP
|
|
182
|
+
* literal, so the screening resolver is never called. The whole existing
|
|
183
|
+
* egress suite passed with the resolver in place *because* its upstream is
|
|
184
|
+
* `127.0.0.1` — a literal, never resolved, never screened. A green suite
|
|
185
|
+
* was the evidence the hole was still open.
|
|
186
|
+
*
|
|
187
|
+
* So the two cases need two checks: names are screened inside the resolver
|
|
188
|
+
* the socket calls, literals are screened here before it dials.
|
|
189
|
+
*/
|
|
190
|
+
export function blockedLiteralReason(host) {
|
|
191
|
+
// The `isIP` guard states the contract: only an address is screened here.
|
|
192
|
+
//
|
|
193
|
+
// It is defence in depth rather than the thing that saves a hostname, and
|
|
194
|
+
// that was measured — removing it kills no test, because `parseV6` refuses
|
|
195
|
+
// `fdsomething.example` and `ff-cdn.example` on its own. It earns its place
|
|
196
|
+
// against the version of this file that does not: the first screen written
|
|
197
|
+
// here matched `/^f[cd]/` against the raw text, and under that screen this
|
|
198
|
+
// line was the only thing standing between an ordinary CDN hostname and a
|
|
199
|
+
// refusal. Keeping it means a future loosening of the parser cannot quietly
|
|
200
|
+
// turn an address screen back into a name filter.
|
|
201
|
+
if (isIP(unbracket(host)) === 0)
|
|
202
|
+
return null;
|
|
203
|
+
return blockedAddressReason(host);
|
|
204
|
+
}
|
|
205
|
+
export class EgressAddressDenied extends Error {
|
|
206
|
+
host;
|
|
207
|
+
address;
|
|
208
|
+
reason;
|
|
209
|
+
constructor(host, address, reason) {
|
|
210
|
+
super(`Egress denied: ${host} resolves to ${address}, which is a ${reason} address. The host is on the allowlist; the address it resolves to is not reachable from a sandbox.`);
|
|
211
|
+
this.name = 'EgressAddressDenied';
|
|
212
|
+
this.host = host;
|
|
213
|
+
this.address = address;
|
|
214
|
+
this.reason = reason;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const platformResolver = (hostname, options, callback) => {
|
|
218
|
+
dnsLookup(hostname, options, callback);
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* A `lookup` implementation that screens before the socket uses the answer.
|
|
222
|
+
*
|
|
223
|
+
* This is deliberately not "resolve, check, then connect to the address we
|
|
224
|
+
* checked". That shape leaves the socket free to resolve again, and the
|
|
225
|
+
* second answer is the one that decides where the bytes go — so a name that
|
|
226
|
+
* alternates records walks straight through a check that passed a moment
|
|
227
|
+
* earlier. Screening inside the resolver the socket itself calls means there
|
|
228
|
+
* is one resolution, and the address that was screened is the address that
|
|
229
|
+
* gets connected to.
|
|
230
|
+
*
|
|
231
|
+
* Every returned address is screened, not just the one chosen. A record set
|
|
232
|
+
* mixing a public address with an inward one is the ordinary shape of this
|
|
233
|
+
* attack, and screening only the winner makes the outcome depend on which
|
|
234
|
+
* record the resolver happened to order first.
|
|
235
|
+
*/
|
|
236
|
+
export function createScreeningLookup(options = {}, isExempt = () => false) {
|
|
237
|
+
const resolver = options.resolve ?? platformResolver;
|
|
238
|
+
const exemptions = options.allowInwardFor ?? [];
|
|
239
|
+
return (hostname, opts, callback) => {
|
|
240
|
+
const wantsAll = typeof opts === 'object' && opts !== null && opts.all === true;
|
|
241
|
+
const family = typeof opts === 'number'
|
|
242
|
+
? opts
|
|
243
|
+
: typeof opts === 'object' && opts !== null
|
|
244
|
+
? (opts.family ?? 0)
|
|
245
|
+
: 0;
|
|
246
|
+
resolver(hostname, { all: true, verbatim: true }, (err, addresses) => {
|
|
247
|
+
if (err) {
|
|
248
|
+
callback(err, '', 0);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const found = addresses ?? [];
|
|
252
|
+
if (found.length === 0) {
|
|
253
|
+
const empty = new Error(`Egress denied: ${hostname} resolved to no addresses.`);
|
|
254
|
+
empty.code = 'ENOTFOUND';
|
|
255
|
+
callback(empty, '', 0);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (!(exemptions.length > 0 && isExempt(hostname, exemptions))) {
|
|
259
|
+
for (const candidate of found) {
|
|
260
|
+
const reason = blockedAddressReason(candidate.address);
|
|
261
|
+
if (reason) {
|
|
262
|
+
callback(new EgressAddressDenied(hostname, candidate.address, reason), '', 0);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const usable = family === 0 ? found : found.filter((a) => a.family === family);
|
|
268
|
+
if (usable.length === 0) {
|
|
269
|
+
const mismatch = new Error(`Egress denied: ${hostname} has no address in the requested family.`);
|
|
270
|
+
mismatch.code = 'ENOTFOUND';
|
|
271
|
+
callback(mismatch, '', 0);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (wantsAll) {
|
|
275
|
+
callback(null, usable);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const first = usable[0];
|
|
279
|
+
if (!first) {
|
|
280
|
+
const none = new Error(`Egress denied: ${hostname} resolved to no usable address.`);
|
|
281
|
+
none.code = 'ENOTFOUND';
|
|
282
|
+
callback(none, '', 0);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
callback(null, first.address, first.family);
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/egress/address.ts"],"names":[],"mappings":"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"}
|
package/dist/egress/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { blockedAddressReason, blockedLiteralReason, createScreeningLookup, EgressAddressDenied, } from './address.js';
|
|
2
|
+
export type { AddressResolver, ScreeningLookupOptions } from './address.js';
|
|
1
3
|
export { isHostAllowed, splitAuthority } from './allowlist.js';
|
|
2
4
|
export { EgressProxy } from './proxy.js';
|
|
3
5
|
export type { BrokeredCredential, EgressProxyOptions, RunningEgressProxy, } from './proxy.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/egress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,YAAY,EACX,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/egress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,YAAY,EACX,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GAClB,MAAM,YAAY,CAAA"}
|
package/dist/egress/index.js
CHANGED
package/dist/egress/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/egress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/egress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/egress/proxy.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ScreeningLookupOptions } from './address.js';
|
|
1
2
|
/**
|
|
2
3
|
* The network boundary a sandbox's egress policy is enforced at.
|
|
3
4
|
*
|
|
@@ -49,6 +50,18 @@ export interface EgressProxyOptions {
|
|
|
49
50
|
*/
|
|
50
51
|
readonly upgradeToHttps?: boolean;
|
|
51
52
|
readonly onDenied?: (host: string, reason: string) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Allowlisted hosts permitted to resolve to an inward address anyway.
|
|
55
|
+
*
|
|
56
|
+
* Matched by the allowlist's own rules, so `.internal.example` covers
|
|
57
|
+
* subdomains. Per host on purpose: an operator who genuinely proxies to
|
|
58
|
+
* one service on a private network needs that one exempted, and a global
|
|
59
|
+
* switch to get it would hand every other allowlisted name the same
|
|
60
|
+
* reach — which is the hole this screen exists to close.
|
|
61
|
+
*/
|
|
62
|
+
readonly allowInwardFor?: readonly string[];
|
|
63
|
+
/** Injected in tests. Defaults to the platform resolver. */
|
|
64
|
+
readonly resolveAddresses?: ScreeningLookupOptions['resolve'];
|
|
52
65
|
}
|
|
53
66
|
export interface RunningEgressProxy {
|
|
54
67
|
readonly port: number;
|
|
@@ -65,10 +78,26 @@ export declare class EgressProxy {
|
|
|
65
78
|
private readonly onDenied;
|
|
66
79
|
/** See the loop guard in `listen`. */
|
|
67
80
|
private selfPort;
|
|
81
|
+
/**
|
|
82
|
+
* The resolver both paths connect through.
|
|
83
|
+
*
|
|
84
|
+
* Held once rather than built per request so there is exactly one place
|
|
85
|
+
* the address screen can be bypassed, and it is visible from here.
|
|
86
|
+
*/
|
|
87
|
+
private readonly lookup;
|
|
88
|
+
private readonly inwardAllowed;
|
|
68
89
|
constructor(options: EgressProxyOptions);
|
|
69
90
|
listen(port?: number): Promise<RunningEgressProxy>;
|
|
70
91
|
private allowed;
|
|
71
92
|
private deny;
|
|
93
|
+
/**
|
|
94
|
+
* Why this target may not be dialled as written, or `null`.
|
|
95
|
+
*
|
|
96
|
+
* Covers the literal-address case only; a name is screened inside
|
|
97
|
+
* `this.lookup`, which the socket calls. Both are needed — see
|
|
98
|
+
* `blockedLiteralReason` for why one cannot cover the other.
|
|
99
|
+
*/
|
|
100
|
+
private literalDenial;
|
|
72
101
|
/** Plain HTTP. The only path where a credential can be stamped on. */
|
|
73
102
|
private handleRequest;
|
|
74
103
|
/**
|
|
@@ -81,6 +110,18 @@ export declare class EgressProxy {
|
|
|
81
110
|
* agent sends anywhere, a strictly larger risk than the one being
|
|
82
111
|
* mitigated. A workload that needs brokering speaks plain HTTP to the
|
|
83
112
|
* proxy and lets it upgrade upstream.
|
|
113
|
+
*
|
|
114
|
+
* **And the allowlist here is a check on the name in the CONNECT line,
|
|
115
|
+
* which is the only thing about this tunnel that is ever in clear text.**
|
|
116
|
+
* The address screen makes it a check on where that name goes, which is a
|
|
117
|
+
* real bound — a permitted name can no longer be a route to the host's own
|
|
118
|
+
* network. It is not a check on what travels afterwards. Inside the tunnel
|
|
119
|
+
* the bytes are the caller's, and the name the caller puts in its own TLS
|
|
120
|
+
* handshake or `Host` header is not visible to this process, so against a
|
|
121
|
+
* determined caller running inside the sandbox this path bounds the
|
|
122
|
+
* DESTINATION and nothing else. Say so plainly rather than let a reader
|
|
123
|
+
* infer that a tunnel to an allowlisted host carries only allowlisted
|
|
124
|
+
* traffic.
|
|
84
125
|
*/
|
|
85
126
|
private handleConnect;
|
|
86
127
|
/** Whether a target names this proxy. See the loop guard in `listen`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/egress/proxy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/egress/proxy.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAG1D;;;;;;;;;;;;;;;;GAgBG;AAEH,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IAClC,qEAAqE;IACrE,QAAQ,CAAC,YAAY,EAAE,MAAM,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAA;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1D;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,4DAA4D;IAC5D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAA;CAC7D;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,eAAe,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,IAAI,CAAA;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAID,qBAAa,WAAW;IACvB,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsD;IAC/E,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAoB;IACpC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;gBAErC,OAAO,EAAE,kBAAkB;IAejC,MAAM,CAAC,IAAI,SAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAyCrC,OAAO;IAWrB,OAAO,CAAC,IAAI;IAIZ;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAKrB,sEAAsE;YACxD,aAAa;IA4F3B;;;;;;;;;;;;;;;;;;;;;;OAsBG;YACW,aAAa;IA+C3B,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,aAAa;CAGrB"}
|
package/dist/egress/proxy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createServer, request as httpRequest } from 'node:http';
|
|
2
2
|
import { request as httpsRequest } from 'node:https';
|
|
3
3
|
import { connect as netConnect } from 'node:net';
|
|
4
|
+
import { EgressAddressDenied, blockedLiteralReason, createScreeningLookup } from './address.js';
|
|
4
5
|
import { isHostAllowed, splitAuthority } from './allowlist.js';
|
|
5
6
|
const DENIED_STATUS = 403;
|
|
6
7
|
export class EgressProxy {
|
|
@@ -10,11 +11,24 @@ export class EgressProxy {
|
|
|
10
11
|
onDenied;
|
|
11
12
|
/** See the loop guard in `listen`. */
|
|
12
13
|
selfPort;
|
|
14
|
+
/**
|
|
15
|
+
* The resolver both paths connect through.
|
|
16
|
+
*
|
|
17
|
+
* Held once rather than built per request so there is exactly one place
|
|
18
|
+
* the address screen can be bypassed, and it is visible from here.
|
|
19
|
+
*/
|
|
20
|
+
lookup;
|
|
21
|
+
inwardAllowed;
|
|
13
22
|
constructor(options) {
|
|
14
23
|
this.resolveAllowed = options.allowedHosts;
|
|
15
24
|
this.credentials = options.credentials ?? [];
|
|
16
25
|
this.upgradeToHttps = options.upgradeToHttps ?? true;
|
|
17
26
|
this.onDenied = options.onDenied;
|
|
27
|
+
this.inwardAllowed = options.allowInwardFor ?? [];
|
|
28
|
+
this.lookup = createScreeningLookup({
|
|
29
|
+
...(options.allowInwardFor ? { allowInwardFor: options.allowInwardFor } : {}),
|
|
30
|
+
...(options.resolveAddresses ? { resolve: options.resolveAddresses } : {}),
|
|
31
|
+
}, isHostAllowed);
|
|
18
32
|
}
|
|
19
33
|
async listen(port = 0) {
|
|
20
34
|
const server = createServer((req, res) => {
|
|
@@ -67,6 +81,18 @@ export class EgressProxy {
|
|
|
67
81
|
deny(host, reason) {
|
|
68
82
|
this.onDenied?.(host, reason);
|
|
69
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Why this target may not be dialled as written, or `null`.
|
|
86
|
+
*
|
|
87
|
+
* Covers the literal-address case only; a name is screened inside
|
|
88
|
+
* `this.lookup`, which the socket calls. Both are needed — see
|
|
89
|
+
* `blockedLiteralReason` for why one cannot cover the other.
|
|
90
|
+
*/
|
|
91
|
+
literalDenial(host) {
|
|
92
|
+
if (this.inwardAllowed.length > 0 && isHostAllowed(host, this.inwardAllowed))
|
|
93
|
+
return null;
|
|
94
|
+
return blockedLiteralReason(host);
|
|
95
|
+
}
|
|
70
96
|
/** Plain HTTP. The only path where a credential can be stamped on. */
|
|
71
97
|
async handleRequest(req, res) {
|
|
72
98
|
const target = parseTarget(req);
|
|
@@ -89,6 +115,17 @@ export class EgressProxy {
|
|
|
89
115
|
res.end(`Egress denied: ${target.host} is not on this sandbox's allowlist.\n`);
|
|
90
116
|
return;
|
|
91
117
|
}
|
|
118
|
+
const literal = this.literalDenial(target.host);
|
|
119
|
+
if (literal) {
|
|
120
|
+
this.deny(target.host, `is a ${literal} address`);
|
|
121
|
+
res.writeHead(DENIED_STATUS, { 'content-type': 'text/plain' });
|
|
122
|
+
// Refused BEFORE the credential is looked up, let alone stamped.
|
|
123
|
+
// The ordering is the point: on this path the token goes on the
|
|
124
|
+
// headers a few lines below, so a check that ran after it would be
|
|
125
|
+
// deciding whether to send a request that already carried it.
|
|
126
|
+
res.end(`Egress denied: ${target.host} is a ${literal} address, which is not reachable from a sandbox.\n`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
92
129
|
const headers = { ...req.headers };
|
|
93
130
|
// The proxy re-issues the request, so hop-by-hop headers about the
|
|
94
131
|
// hop that just ended must not be forwarded.
|
|
@@ -108,11 +145,28 @@ export class EgressProxy {
|
|
|
108
145
|
method: req.method,
|
|
109
146
|
path: target.path,
|
|
110
147
|
headers,
|
|
148
|
+
// `host` stays the NAME so SNI and certificate validation still
|
|
149
|
+
// check the name the allowlist approved; only the address the
|
|
150
|
+
// socket dials is screened. Swapping in the address here would
|
|
151
|
+
// break TLS verification, which is the wrong way to fix this.
|
|
152
|
+
lookup: this.lookup,
|
|
111
153
|
}, (response) => {
|
|
112
154
|
res.writeHead(response.statusCode ?? 502, response.headers);
|
|
113
155
|
response.pipe(res);
|
|
114
156
|
});
|
|
115
157
|
upstream.on('error', (err) => {
|
|
158
|
+
// An address denial is a policy refusal, not a network fault, and
|
|
159
|
+
// telling them apart is the difference between an agent that stops
|
|
160
|
+
// and one that retries a forbidden host forever. The credential is
|
|
161
|
+
// already on `headers` at this point and has still not left the
|
|
162
|
+
// process: the socket never connected, so nothing was written.
|
|
163
|
+
if (err instanceof EgressAddressDenied) {
|
|
164
|
+
this.deny(err.host, `resolves to a ${err.reason} address`);
|
|
165
|
+
if (!res.headersSent)
|
|
166
|
+
res.writeHead(DENIED_STATUS, { 'content-type': 'text/plain' });
|
|
167
|
+
res.end(`${err.message}\n`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
116
170
|
if (!res.headersSent)
|
|
117
171
|
res.writeHead(502, { 'content-type': 'text/plain' });
|
|
118
172
|
res.end(`Upstream request failed: ${err.message}\n`);
|
|
@@ -129,6 +183,18 @@ export class EgressProxy {
|
|
|
129
183
|
* agent sends anywhere, a strictly larger risk than the one being
|
|
130
184
|
* mitigated. A workload that needs brokering speaks plain HTTP to the
|
|
131
185
|
* proxy and lets it upgrade upstream.
|
|
186
|
+
*
|
|
187
|
+
* **And the allowlist here is a check on the name in the CONNECT line,
|
|
188
|
+
* which is the only thing about this tunnel that is ever in clear text.**
|
|
189
|
+
* The address screen makes it a check on where that name goes, which is a
|
|
190
|
+
* real bound — a permitted name can no longer be a route to the host's own
|
|
191
|
+
* network. It is not a check on what travels afterwards. Inside the tunnel
|
|
192
|
+
* the bytes are the caller's, and the name the caller puts in its own TLS
|
|
193
|
+
* handshake or `Host` header is not visible to this process, so against a
|
|
194
|
+
* determined caller running inside the sandbox this path bounds the
|
|
195
|
+
* DESTINATION and nothing else. Say so plainly rather than let a reader
|
|
196
|
+
* infer that a tunnel to an allowlisted host carries only allowlisted
|
|
197
|
+
* traffic.
|
|
132
198
|
*/
|
|
133
199
|
async handleConnect(req, socket, head) {
|
|
134
200
|
const { host, port } = splitAuthority(req.url ?? '');
|
|
@@ -138,14 +204,29 @@ export class EgressProxy {
|
|
|
138
204
|
socket.end();
|
|
139
205
|
return;
|
|
140
206
|
}
|
|
141
|
-
const
|
|
207
|
+
const literal = this.literalDenial(host);
|
|
208
|
+
if (literal) {
|
|
209
|
+
this.deny(host, `is a ${literal} address`);
|
|
210
|
+
socket.write(`HTTP/1.1 ${DENIED_STATUS} Forbidden\r\nContent-Type: text/plain\r\n\r\nEgress denied: ${host} is a ${literal} address, which is not reachable from a sandbox.\n`);
|
|
211
|
+
socket.end();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// Same screened resolver as the plain path. The tunnel carries no
|
|
215
|
+
// brokered credential, so the loss here is reach rather than a token —
|
|
216
|
+
// but an allowlisted name pointing inward still turns this proxy into
|
|
217
|
+
// a route to the host's own network, which is what a sandbox is for.
|
|
218
|
+
const upstream = netConnect({ port: port ?? 443, host, lookup: this.lookup }, () => {
|
|
142
219
|
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
|
|
143
220
|
if (head.length > 0)
|
|
144
221
|
upstream.write(head);
|
|
145
222
|
upstream.pipe(socket);
|
|
146
223
|
socket.pipe(upstream);
|
|
147
224
|
});
|
|
148
|
-
upstream.on('error', () => {
|
|
225
|
+
upstream.on('error', (err) => {
|
|
226
|
+
if (err instanceof EgressAddressDenied) {
|
|
227
|
+
this.deny(err.host, `resolves to a ${err.reason} address`);
|
|
228
|
+
socket.write(`HTTP/1.1 ${DENIED_STATUS} Forbidden\r\nContent-Type: text/plain\r\n\r\n${err.message}\n`);
|
|
229
|
+
}
|
|
149
230
|
socket.end();
|
|
150
231
|
});
|
|
151
232
|
socket.on('error', () => {
|
package/dist/egress/proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/egress/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,UAAU,CAAA;AAGhD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/egress/proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -155,6 +155,22 @@ export interface ContainerBackendConfig {
|
|
|
155
155
|
* separately by `EgressPolicy`.
|
|
156
156
|
*/
|
|
157
157
|
readonly network?: 'none' | 'bridge' | string;
|
|
158
|
+
/**
|
|
159
|
+
* Allowlisted hosts permitted to resolve to an inward address anyway.
|
|
160
|
+
*
|
|
161
|
+
* The egress boundary refuses a host that resolves to loopback, a
|
|
162
|
+
* private range, or the link-local block cloud metadata services answer
|
|
163
|
+
* on — whatever the allowlist says, because an allowlisted name whose
|
|
164
|
+
* DNS someone else controls is a permitted spelling rather than a
|
|
165
|
+
* permitted destination. A deployment that genuinely proxies to one
|
|
166
|
+
* service on a private network names that service here.
|
|
167
|
+
*
|
|
168
|
+
* Per host, matched by the allowlist's own rules so `.internal.example`
|
|
169
|
+
* covers subdomains. There is deliberately no switch that turns the
|
|
170
|
+
* screen off: one would hand every other allowlisted name the same
|
|
171
|
+
* reach, which is the hole the screen exists to close.
|
|
172
|
+
*/
|
|
173
|
+
readonly allowInwardFor?: readonly string[];
|
|
158
174
|
/**
|
|
159
175
|
* Optional `--label key=value` pairs applied to the spawned
|
|
160
176
|
* container. Hosts use this to make the container findable from
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|