edgeaegis 2026.10.1

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.
Files changed (158) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +10 -0
  3. package/README.md +215 -0
  4. package/config.yml +29 -0
  5. package/origin/cloudflare/app/config.yml +2 -0
  6. package/origin/cloudflare/app/index.js +4 -0
  7. package/origin/edgeone/app/config.yml +2 -0
  8. package/origin/edgeone/app/index.js +4 -0
  9. package/origin/esa/app/config.yml +2 -0
  10. package/origin/esa/app/index.js +4 -0
  11. package/origin/netlify/app/config.yml +2 -0
  12. package/origin/netlify/app/index.js +4 -0
  13. package/origin/vercel/app/config.yml +2 -0
  14. package/origin/vercel/app/index.js +4 -0
  15. package/package.json +123 -0
  16. package/respond/403.html +2 -0
  17. package/respond/403.json +1 -0
  18. package/rules/allowlist.yml +2 -0
  19. package/rules/emergency.conf +4 -0
  20. package/rules/local.conf +2 -0
  21. package/rules/seclang-bundle.json +360 -0
  22. package/rules/seclang-upstreams.json +14 -0
  23. package/rules/setup.conf +15 -0
  24. package/secret/credentials.example.yml +7 -0
  25. package/secret/relay-server.example.yml +10 -0
  26. package/tools/.build/scr/adapters/cloudflare/runtime.d.ts +18 -0
  27. package/tools/.build/scr/adapters/cloudflare/runtime.js +16 -0
  28. package/tools/.build/scr/adapters/cloudflare/runtime.js.map +1 -0
  29. package/tools/.build/scr/adapters/cloudflare/worker.js +25 -0
  30. package/tools/.build/scr/adapters/edgeone/worker.js +7 -0
  31. package/tools/.build/scr/adapters/esa/worker.js +5 -0
  32. package/tools/.build/scr/adapters/forward.d.ts +4 -0
  33. package/tools/.build/scr/adapters/forward.js +25 -0
  34. package/tools/.build/scr/adapters/forward.js.map +1 -0
  35. package/tools/.build/scr/adapters/handler.js +39 -0
  36. package/tools/.build/scr/adapters/ingress.d.ts +10 -0
  37. package/tools/.build/scr/adapters/ingress.js +62 -0
  38. package/tools/.build/scr/adapters/ingress.js.map +1 -0
  39. package/tools/.build/scr/adapters/netlify/worker.js +7 -0
  40. package/tools/.build/scr/adapters/runtime.d.ts +33 -0
  41. package/tools/.build/scr/adapters/runtime.js +50 -0
  42. package/tools/.build/scr/adapters/runtime.js.map +1 -0
  43. package/tools/.build/scr/adapters/vercel/worker.js +7 -0
  44. package/tools/.build/scr/cli/config.d.ts +2 -0
  45. package/tools/.build/scr/cli/config.js +23 -0
  46. package/tools/.build/scr/cli/config.js.map +1 -0
  47. package/tools/.build/scr/cli/deployment.d.ts +15 -0
  48. package/tools/.build/scr/cli/deployment.js +108 -0
  49. package/tools/.build/scr/cli/deployment.js.map +1 -0
  50. package/tools/.build/scr/cli/init.d.ts +2 -0
  51. package/tools/.build/scr/cli/init.js +62 -0
  52. package/tools/.build/scr/cli/init.js.map +1 -0
  53. package/tools/.build/scr/cli/main.d.ts +2 -0
  54. package/tools/.build/scr/cli/main.js +99 -0
  55. package/tools/.build/scr/cli/main.js.map +1 -0
  56. package/tools/.build/scr/cli/relay-serve.d.ts +1 -0
  57. package/tools/.build/scr/cli/relay-serve.js +48 -0
  58. package/tools/.build/scr/cli/relay-serve.js.map +1 -0
  59. package/tools/.build/scr/cli/responses.d.ts +2 -0
  60. package/tools/.build/scr/cli/responses.js +31 -0
  61. package/tools/.build/scr/cli/responses.js.map +1 -0
  62. package/tools/.build/scr/cli/serve.d.ts +1 -0
  63. package/tools/.build/scr/cli/serve.js +132 -0
  64. package/tools/.build/scr/cli/serve.js.map +1 -0
  65. package/tools/.build/scr/config.d.ts +39 -0
  66. package/tools/.build/scr/config.js +89 -0
  67. package/tools/.build/scr/config.js.map +1 -0
  68. package/tools/.build/scr/core/types.d.ts +27 -0
  69. package/tools/.build/scr/core/types.js +34 -0
  70. package/tools/.build/scr/core/types.js.map +1 -0
  71. package/tools/.build/scr/core/version.d.ts +1 -0
  72. package/tools/.build/scr/core/version.js +3 -0
  73. package/tools/.build/scr/core/version.js.map +1 -0
  74. package/tools/.build/scr/http-boundary/index.d.ts +19 -0
  75. package/tools/.build/scr/http-boundary/index.js +173 -0
  76. package/tools/.build/scr/http-boundary/index.js.map +1 -0
  77. package/tools/.build/scr/http-boundary/json.d.ts +2 -0
  78. package/tools/.build/scr/http-boundary/json.js +90 -0
  79. package/tools/.build/scr/http-boundary/json.js.map +1 -0
  80. package/tools/.build/scr/origin/relay.d.ts +20 -0
  81. package/tools/.build/scr/origin/relay.js +221 -0
  82. package/tools/.build/scr/origin/relay.js.map +1 -0
  83. package/tools/.build/scr/origin/replay-node.d.ts +8 -0
  84. package/tools/.build/scr/origin/replay-node.js +36 -0
  85. package/tools/.build/scr/origin/replay-node.js.map +1 -0
  86. package/tools/.build/scr/origin/types.d.ts +18 -0
  87. package/tools/.build/scr/origin/types.js +2 -0
  88. package/tools/.build/scr/origin/types.js.map +1 -0
  89. package/tools/.build/scr/runtime/allowlist.d.ts +21 -0
  90. package/tools/.build/scr/runtime/allowlist.js +84 -0
  91. package/tools/.build/scr/runtime/allowlist.js.map +1 -0
  92. package/tools/.build/scr/runtime/browser-cache.d.ts +7 -0
  93. package/tools/.build/scr/runtime/browser-cache.js +50 -0
  94. package/tools/.build/scr/runtime/browser-cache.js.map +1 -0
  95. package/tools/.build/scr/runtime/error-pages.d.ts +10 -0
  96. package/tools/.build/scr/runtime/error-pages.js +72 -0
  97. package/tools/.build/scr/runtime/error-pages.js.map +1 -0
  98. package/tools/.build/scr/runtime/index.d.ts +54 -0
  99. package/tools/.build/scr/runtime/index.js +355 -0
  100. package/tools/.build/scr/runtime/index.js.map +1 -0
  101. package/tools/.build/scr/runtime/node.d.ts +3 -0
  102. package/tools/.build/scr/runtime/node.js +97 -0
  103. package/tools/.build/scr/runtime/node.js.map +1 -0
  104. package/tools/.build/scr/runtime/proxy.d.ts +12 -0
  105. package/tools/.build/scr/runtime/proxy.js +177 -0
  106. package/tools/.build/scr/runtime/proxy.js.map +1 -0
  107. package/tools/.build/scr/runtime/stream.d.ts +8 -0
  108. package/tools/.build/scr/runtime/stream.js +72 -0
  109. package/tools/.build/scr/runtime/stream.js.map +1 -0
  110. package/tools/.build/scr/seclang/body.d.ts +13 -0
  111. package/tools/.build/scr/seclang/body.js +109 -0
  112. package/tools/.build/scr/seclang/body.js.map +1 -0
  113. package/tools/.build/scr/seclang/bytes.d.ts +5 -0
  114. package/tools/.build/scr/seclang/bytes.js +38 -0
  115. package/tools/.build/scr/seclang/bytes.js.map +1 -0
  116. package/tools/.build/scr/seclang/index.d.ts +166 -0
  117. package/tools/.build/scr/seclang/index.js +1519 -0
  118. package/tools/.build/scr/seclang/index.js.map +1 -0
  119. package/tools/.build/scr/seclang/json.d.ts +2 -0
  120. package/tools/.build/scr/seclang/json.js +87 -0
  121. package/tools/.build/scr/seclang/json.js.map +1 -0
  122. package/tools/.build/scr/seclang/libinjection.d.ts +9 -0
  123. package/tools/.build/scr/seclang/libinjection.js +59 -0
  124. package/tools/.build/scr/seclang/libinjection.js.map +1 -0
  125. package/tools/.build/scr/seclang/node.d.ts +22 -0
  126. package/tools/.build/scr/seclang/node.js +113 -0
  127. package/tools/.build/scr/seclang/node.js.map +1 -0
  128. package/tools/.build/scr/seclang/pcre2.d.ts +23 -0
  129. package/tools/.build/scr/seclang/pcre2.js +153 -0
  130. package/tools/.build/scr/seclang/pcre2.js.map +1 -0
  131. package/tools/.build/scr/seclang/sources.d.ts +6 -0
  132. package/tools/.build/scr/seclang/sources.js +59 -0
  133. package/tools/.build/scr/seclang/sources.js.map +1 -0
  134. package/tools/.build/scr/seclang/state.d.ts +17 -0
  135. package/tools/.build/scr/seclang/state.js +53 -0
  136. package/tools/.build/scr/seclang/state.js.map +1 -0
  137. package/tools/.build/scr/seclang/syntax.d.ts +9 -0
  138. package/tools/.build/scr/seclang/syntax.js +74 -0
  139. package/tools/.build/scr/seclang/syntax.js.map +1 -0
  140. package/tools/.build/scr/seclang/transforms.d.ts +3 -0
  141. package/tools/.build/scr/seclang/transforms.js +157 -0
  142. package/tools/.build/scr/seclang/transforms.js.map +1 -0
  143. package/tools/.build/scr/seclang/unicode.d.ts +2 -0
  144. package/tools/.build/scr/seclang/unicode.js +19 -0
  145. package/tools/.build/scr/seclang/unicode.js.map +1 -0
  146. package/tools/.build/scr/seclang/vendor/LIBINJECTION-LICENSE +33 -0
  147. package/tools/.build/scr/seclang/vendor/PCRE2-NOTICE +47 -0
  148. package/tools/.build/scr/seclang/vendor/PCRE2-WRAPPER-LICENSE +21 -0
  149. package/tools/.build/scr/seclang/vendor/UNICODE-DATA-NOTICE +6 -0
  150. package/tools/.build/scr/seclang/vendor/libinjection.json +7 -0
  151. package/tools/.build/scr/seclang/vendor/libinjection.wasm +0 -0
  152. package/tools/.build/scr/seclang/vendor/pcre2.json +7 -0
  153. package/tools/.build/scr/seclang/vendor/pcre2.wasm +0 -0
  154. package/tools/.build/scr/seclang/vendor/unicode.json +378 -0
  155. package/tools/build-platform.mjs +199 -0
  156. package/tools/platform-command.mjs +59 -0
  157. package/tools/sync-native-seclang.mjs +155 -0
  158. package/tools/verify-full-crs.mjs +118 -0
@@ -0,0 +1 @@
1
+ export declare const SHIELD_VERSION = "2026.10.1";
@@ -0,0 +1,3 @@
1
+ // Generated from package.json by tools/sync-version.mjs.
2
+ export const SHIELD_VERSION = "2026.10.1";
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../../scr/core/version.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC"}
@@ -0,0 +1,19 @@
1
+ export { parseStrictJson } from "./json.js";
2
+ export interface BoundaryLimits {
3
+ maxBodyBytes: number;
4
+ maxUrlBytes: number;
5
+ maxHeaderBytes: number;
6
+ maxHeaders: number;
7
+ bodyTimeoutMs: number;
8
+ }
9
+ export declare const defaultLimits: BoundaryLimits;
10
+ export declare function limitsWith(input?: Partial<BoundaryLimits>): BoundaryLimits;
11
+ /** Must run BEFORE constructing a URL/Request when the host exposes the original target. */
12
+ export declare function canonicalPath(target: string): string;
13
+ /** Raw framing inspection is available ONLY to the local Node adapter, not to Web Request. */
14
+ export declare function checkRawHeaders(raw: readonly string[]): void;
15
+ export declare function checkBoundary(request: Request, limits: BoundaryLimits, publicHosts: readonly string[], rawTarget?: string, mode?: "http" | "websocket"): {
16
+ url: URL;
17
+ path: string;
18
+ };
19
+ export declare function readBody(request: Request, limits: BoundaryLimits): Promise<Uint8Array>;
@@ -0,0 +1,173 @@
1
+ import { requireInteger, ShieldError } from "../core/types.js";
2
+ export { parseStrictJson } from "./json.js";
3
+ export const defaultLimits = {
4
+ maxBodyBytes: 262144,
5
+ maxUrlBytes: 8192,
6
+ maxHeaderBytes: 16384,
7
+ maxHeaders: 64,
8
+ bodyTimeoutMs: 5000,
9
+ };
10
+ export function limitsWith(input = {}) {
11
+ const limits = { ...defaultLimits, ...input };
12
+ requireInteger(limits.maxBodyBytes, 0, 16_777_216, "maxBodyBytes");
13
+ requireInteger(limits.maxUrlBytes, 256, 65536, "maxUrlBytes");
14
+ requireInteger(limits.maxHeaderBytes, 256, 65536, "maxHeaderBytes");
15
+ requireInteger(limits.maxHeaders, 1, 256, "maxHeaders");
16
+ requireInteger(limits.bodyTimeoutMs, 1, 60000, "bodyTimeoutMs");
17
+ return limits;
18
+ }
19
+ /** Must run BEFORE constructing a URL/Request when the host exposes the original target. */
20
+ export function canonicalPath(target) {
21
+ const path = target.split("?", 1)[0] ?? "";
22
+ if (!path.startsWith("/") || path.startsWith("//") || /[\\;#\u0000-\u0020\u007f]/.test(path))
23
+ throw new ShieldError("ambiguous-path");
24
+ if (/%(?:2f|5c|25|2e|00|3f|23|3b)/i.test(path))
25
+ throw new ShieldError("ambiguous-path-encoding");
26
+ let decoded;
27
+ try {
28
+ decoded = decodeURIComponent(path);
29
+ }
30
+ catch {
31
+ throw new ShieldError("invalid-path-encoding");
32
+ }
33
+ if (decoded.includes("//") ||
34
+ /(?:^|\/)\.{1,2}(?:\/|$)/.test(decoded) ||
35
+ /[\\;#?\u0000-\u0020\u007f]/.test(decoded) ||
36
+ decoded !== decoded.normalize("NFC"))
37
+ throw new ShieldError("ambiguous-path");
38
+ return decoded;
39
+ }
40
+ /** Raw framing inspection is available ONLY to the local Node adapter, not to Web Request. */
41
+ export function checkRawHeaders(raw) {
42
+ if (raw.length > 128)
43
+ throw new ShieldError("too-many-raw-headers", 431);
44
+ const seen = new Set();
45
+ for (let i = 0; i < raw.length; i += 2) {
46
+ const name = (raw[i] ?? "").toLowerCase();
47
+ const value = raw[i + 1] ?? "";
48
+ if (!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(name) ||
49
+ /[\u0000-\u0008\u000a-\u001f\u007f]/.test(value))
50
+ throw new ShieldError("invalid-raw-header");
51
+ if (seen.has(name) &&
52
+ ["host", "content-length", "transfer-encoding", "authorization"].includes(name))
53
+ throw new ShieldError("duplicate-security-header");
54
+ seen.add(name);
55
+ }
56
+ if (seen.has("content-length") && seen.has("transfer-encoding"))
57
+ throw new ShieldError("ambiguous-framing");
58
+ }
59
+ export function checkBoundary(request, limits, publicHosts, rawTarget, mode = "http") {
60
+ if (new TextEncoder().encode(request.url).length > limits.maxUrlBytes)
61
+ throw new ShieldError("url-too-large", 414);
62
+ const url = new URL(request.url);
63
+ if (!["https:", "http:"].includes(url.protocol) ||
64
+ url.username ||
65
+ url.password ||
66
+ !publicHosts.includes(url.host))
67
+ throw new ShieldError("untrusted-host", 421);
68
+ if (request.headers.has("host") && request.headers.get("host") !== url.host)
69
+ throw new ShieldError("host-mismatch", 421);
70
+ if (rawTarget !== undefined)
71
+ canonicalPath(rawTarget);
72
+ const path = canonicalPath(url.pathname);
73
+ try {
74
+ decodeURIComponent(url.search);
75
+ }
76
+ catch {
77
+ throw new ShieldError("invalid-query-encoding");
78
+ }
79
+ if ([...url.searchParams].length > 128)
80
+ throw new ShieldError("too-many-query-fields");
81
+ let headerBytes = 0;
82
+ let headerCount = 0;
83
+ for (const [name, value] of request.headers) {
84
+ headerCount++;
85
+ headerBytes += new TextEncoder().encode(name + value).length + 4;
86
+ if (/[\u0000-\u0008\u000a-\u001f\u007f]/.test(value))
87
+ throw new ShieldError("invalid-header");
88
+ }
89
+ if (headerBytes > limits.maxHeaderBytes || headerCount > limits.maxHeaders)
90
+ throw new ShieldError("headers-too-large", 431);
91
+ const cl = request.headers.get("content-length");
92
+ const te = request.headers.get("transfer-encoding");
93
+ if (request.headers.has("expect") || request.headers.has("trailer"))
94
+ throw new ShieldError("unsupported-expect-or-trailers", 417);
95
+ if (["GET", "HEAD"].includes(request.method) && (te !== null || Number(cl ?? "0") > 0))
96
+ throw new ShieldError("body-not-allowed-for-method");
97
+ if (te && (cl !== null || te.toLowerCase() !== "chunked"))
98
+ throw new ShieldError("ambiguous-framing");
99
+ if (cl !== null && (!/^(0|[1-9][0-9]*)$/.test(cl) || !Number.isSafeInteger(Number(cl))))
100
+ throw new ShieldError("invalid-content-length");
101
+ if (cl !== null && Number(cl) > limits.maxBodyBytes)
102
+ throw new ShieldError("body-too-large", 413);
103
+ const connection = request.headers.get("connection");
104
+ if (connection
105
+ ?.split(",")
106
+ .some((s) => !["close", "keep-alive", ...(mode === "websocket" ? ["upgrade"] : [])].includes(s.trim().toLowerCase())))
107
+ throw new ShieldError("unsafe-connection-header");
108
+ if ((request.headers.has("upgrade") && mode !== "websocket") ||
109
+ request.method === "CONNECT" ||
110
+ request.method === "TRACE")
111
+ throw new ShieldError("unsupported-protocol", 405);
112
+ if (mode === "websocket" &&
113
+ (request.method !== "GET" ||
114
+ request.headers.get("upgrade")?.toLowerCase() !== "websocket" ||
115
+ request.headers.get("sec-websocket-version") !== "13" ||
116
+ !/^[A-Za-z0-9+/]{22}==$/.test(request.headers.get("sec-websocket-key") ?? "") ||
117
+ te !== null ||
118
+ Number(cl ?? "0") !== 0))
119
+ throw new ShieldError("invalid-websocket-handshake", 400);
120
+ if (request.headers.has("content-encoding") &&
121
+ request.headers.get("content-encoding") !== "identity")
122
+ throw new ShieldError("unsupported-content-encoding", 415);
123
+ return { url, path };
124
+ }
125
+ export async function readBody(request, limits) {
126
+ if (!request.body) {
127
+ if (Number(request.headers.get("content-length") ?? "0") !== 0)
128
+ throw new ShieldError("body-length-mismatch");
129
+ return new Uint8Array();
130
+ }
131
+ const reader = request.body.getReader();
132
+ let timer;
133
+ const chunks = [];
134
+ let size = 0;
135
+ try {
136
+ const timeout = new Promise((_, reject) => {
137
+ timer = setTimeout(() => reject(new ShieldError("body-timeout", 408)), limits.bodyTimeoutMs);
138
+ });
139
+ await Promise.race([
140
+ (async () => {
141
+ while (true) {
142
+ const item = await reader.read();
143
+ if (item.done)
144
+ break;
145
+ size += item.value.byteLength;
146
+ if (size > limits.maxBodyBytes)
147
+ throw new ShieldError("body-too-large", 413);
148
+ chunks.push(item.value.slice());
149
+ }
150
+ })(),
151
+ timeout,
152
+ ]);
153
+ }
154
+ catch (error) {
155
+ void reader.cancel().catch(() => { });
156
+ throw error;
157
+ }
158
+ finally {
159
+ if (timer)
160
+ clearTimeout(timer);
161
+ }
162
+ const cl = request.headers.get("content-length");
163
+ if (cl !== null && Number(cl) !== size)
164
+ throw new ShieldError("body-length-mismatch");
165
+ const body = new Uint8Array(size);
166
+ let offset = 0;
167
+ for (const chunk of chunks) {
168
+ body.set(chunk, offset);
169
+ offset += chunk.byteLength;
170
+ }
171
+ return body;
172
+ }
173
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../scr/http-boundary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAS5C,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,YAAY,EAAE,MAAM;IACpB,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,EAAE;IACd,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,KAAK,GAA4B,EAAE;IAC5D,MAAM,MAAM,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,EAAE,CAAC;IAC9C,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;IACnE,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAC9D,cAAc,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACpE,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IACxD,cAAc,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1F,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC1C,IAAI,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,yBAAyB,CAAC,CAAC;IACjG,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,uBAAuB,CAAC,CAAC;IACjD,CAAC;IACD,IACE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QACtB,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC;QACvC,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC;QAC1C,OAAO,KAAK,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;QAEpC,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,GAAsB;IACpD,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG;QAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,IACE,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;YACxC,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC;YAEhD,MAAM,IAAI,WAAW,CAAC,oBAAoB,CAAC,CAAC;QAC9C,IACE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACd,CAAC,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAE/E,MAAM,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAC7D,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,MAAsB,EACtB,WAA8B,EAC9B,SAAkB,EAClB,IAAI,GAAyB,MAAM;IAEnC,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW;QACnE,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IACE,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC3C,GAAG,CAAC,QAAQ;QACZ,GAAG,CAAC,QAAQ;QACZ,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAE/B,MAAM,IAAI,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI;QACzE,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IAC9C,IAAI,SAAS,KAAK,SAAS;QAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,GAAG;QAAE,MAAM,IAAI,WAAW,CAAC,uBAAuB,CAAC,CAAC;IACvF,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5C,WAAW,EAAE,CAAC;QACd,WAAW,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACjE,IAAI,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,WAAW,GAAG,MAAM,CAAC,cAAc,IAAI,WAAW,GAAG,MAAM,CAAC,UAAU;QACxE,MAAM,IAAI,WAAW,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACjD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACpD,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QACjE,MAAM,IAAI,WAAW,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACpF,MAAM,IAAI,WAAW,CAAC,6BAA6B,CAAC,CAAC;IACvD,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC;QACvD,MAAM,IAAI,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC7C,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACrF,MAAM,IAAI,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAClD,IAAI,EAAE,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,YAAY;QAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAClG,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACrD,IACE,UAAU;QACR,EAAE,KAAK,CAAC,GAAG,CAAC;SACX,IAAI,CACH,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAC7E,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CACvB,CACJ;QAEH,MAAM,IAAI,WAAW,CAAC,0BAA0B,CAAC,CAAC;IACpD,IACE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,KAAK,WAAW,CAAC;QACxD,OAAO,CAAC,MAAM,KAAK,SAAS;QAC5B,OAAO,CAAC,MAAM,KAAK,OAAO;QAE1B,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IACrD,IACE,IAAI,KAAK,WAAW;QACpB,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;YACvB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,WAAW;YAC7D,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,IAAI;YACrD,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC;YAC7E,EAAE,KAAK,IAAI;YACX,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAE1B,MAAM,IAAI,WAAW,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAC5D,IACE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACvC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,UAAU;QAEtD,MAAM,IAAI,WAAW,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;IAC7D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAgB,EAAE,MAAsB;IACrE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;YAC5D,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC;QAChD,OAAO,IAAI,UAAU,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACxC,IAAI,KAAgD,CAAC;IACrD,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YAC/C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,CAAC,KAAK,IAAI,EAAE;gBACV,OAAO,IAAI,EAAE,CAAC;oBACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;oBACjC,IAAI,IAAI,CAAC,IAAI;wBAAE,MAAM;oBACrB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;oBAC9B,IAAI,IAAI,GAAG,MAAM,CAAC,YAAY;wBAAE,MAAM,IAAI,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;oBAC7E,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC,CAAC,EAAE;YACJ,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACjD,IAAI,EAAE,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Reject parser differentials: duplicate object keys, non-finite numbers and excessive nesting. */
2
+ export declare function parseStrictJson(text: string): unknown;
@@ -0,0 +1,90 @@
1
+ import { ShieldError } from "../core/types.js";
2
+ /** Reject parser differentials: duplicate object keys, non-finite numbers and excessive nesting. */
3
+ export function parseStrictJson(text) {
4
+ let offset = 0;
5
+ let nodes = 0;
6
+ const ws = () => {
7
+ while (/[\x20\t\r\n]/.test(text[offset] ?? "!"))
8
+ offset++;
9
+ };
10
+ const fail = () => {
11
+ throw new ShieldError("ambiguous-or-invalid-json");
12
+ };
13
+ function string() {
14
+ const start = offset;
15
+ if (text[offset++] !== '"')
16
+ return fail();
17
+ while (offset < text.length) {
18
+ const c = text[offset++];
19
+ if (c === '"') {
20
+ try {
21
+ return JSON.parse(text.slice(start, offset));
22
+ }
23
+ catch {
24
+ return fail();
25
+ }
26
+ }
27
+ if (c === "\\")
28
+ offset++;
29
+ }
30
+ return fail();
31
+ }
32
+ function value(depth) {
33
+ if (depth > 32 || ++nodes > 16384)
34
+ fail();
35
+ ws();
36
+ const c = text[offset];
37
+ if (c === '"') {
38
+ string();
39
+ return;
40
+ }
41
+ if (c === "{" || c === "[") {
42
+ const object = c === "{";
43
+ const close = object ? "}" : "]";
44
+ const keys = new Set();
45
+ offset++;
46
+ ws();
47
+ if (text[offset] === close) {
48
+ offset++;
49
+ return;
50
+ }
51
+ while (true) {
52
+ if (object) {
53
+ ws();
54
+ const key = string();
55
+ if (keys.has(key))
56
+ fail();
57
+ keys.add(key);
58
+ ws();
59
+ if (text[offset++] !== ":")
60
+ fail();
61
+ }
62
+ value(depth + 1);
63
+ ws();
64
+ if (text[offset] === close) {
65
+ offset++;
66
+ return;
67
+ }
68
+ if (text[offset++] !== ",")
69
+ fail();
70
+ }
71
+ }
72
+ const token = /^(?:true|false|null|-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)/.exec(text.slice(offset))?.[0];
73
+ if (!token)
74
+ throw new ShieldError("ambiguous-or-invalid-json");
75
+ if (/^-?[0-9]/.test(token) && !Number.isFinite(Number(token)))
76
+ fail();
77
+ offset += token.length;
78
+ }
79
+ value(0);
80
+ ws();
81
+ if (offset !== text.length)
82
+ fail();
83
+ try {
84
+ return JSON.parse(text);
85
+ }
86
+ catch {
87
+ return fail();
88
+ }
89
+ }
90
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../../../scr/http-boundary/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface ReplayStore {
2
+ claim(id: string, expiresAt: number): Promise<boolean>;
3
+ }
4
+ export declare function createRelayTransport(options: {
5
+ endpoint: string;
6
+ serverPublicKey: JsonWebKey;
7
+ authenticationKey: string;
8
+ maxBytes?: number;
9
+ fetch?: typeof fetch;
10
+ now?: () => number;
11
+ }): Promise<(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>>;
12
+ export declare function createRelayServer(options: {
13
+ serverPrivateKey: JsonWebKey;
14
+ authenticationKey: string;
15
+ originToken: string;
16
+ business: (request: Request) => Promise<Response>;
17
+ replay: ReplayStore;
18
+ maxBytes?: number;
19
+ now?: () => number;
20
+ }): Promise<(request: Request) => Promise<Response>>;
@@ -0,0 +1,221 @@
1
+ import { stableJson } from "../core/types.js";
2
+ const encoder = new TextEncoder(), decoder = new TextDecoder("utf-8", { fatal: true });
3
+ const bytes = (value) => value;
4
+ function b64(value) {
5
+ let text = "";
6
+ for (let i = 0; i < value.length; i += 8192)
7
+ text += String.fromCharCode(...value.subarray(i, i + 8192));
8
+ return btoa(text).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
9
+ }
10
+ function unb64(value, limit) {
11
+ if (typeof value !== "string" ||
12
+ value.length > Math.ceil((limit * 4) / 3) + 4 ||
13
+ !/^[\w-]*$/.test(value))
14
+ throw new Error("Invalid relay encoding");
15
+ const binary = atob(value.replaceAll("-", "+").replaceAll("_", "/"));
16
+ if (binary.length > limit)
17
+ throw new Error("Relay value exceeds limit");
18
+ return Uint8Array.from(binary, (c) => c.charCodeAt(0));
19
+ }
20
+ async function readBytes(response, limit) {
21
+ if (!response.body)
22
+ return new Uint8Array();
23
+ const reader = response.body.getReader(), chunks = [];
24
+ let length = 0;
25
+ let timer;
26
+ const timeout = new Promise((_, reject) => {
27
+ timer = setTimeout(() => reject(new Error("Relay read deadline exceeded")), 10000);
28
+ });
29
+ try {
30
+ while (true) {
31
+ const item = await Promise.race([reader.read(), timeout]);
32
+ if (item.done)
33
+ break;
34
+ length += item.value.length;
35
+ if (length > limit)
36
+ throw new Error("Relay body exceeds limit");
37
+ chunks.push(item.value);
38
+ }
39
+ }
40
+ catch (error) {
41
+ void reader.cancel().catch(() => { });
42
+ throw error;
43
+ }
44
+ finally {
45
+ clearTimeout(timer);
46
+ }
47
+ const result = new Uint8Array(length);
48
+ let offset = 0;
49
+ for (const chunk of chunks) {
50
+ result.set(chunk, offset);
51
+ offset += chunk.length;
52
+ }
53
+ return result;
54
+ }
55
+ function bodyLimit(value) {
56
+ const limit = value ?? 8 * 1024 * 1024;
57
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 16 * 1024 * 1024)
58
+ throw new Error("Relay byte limit must be 1..16777216");
59
+ return limit;
60
+ }
61
+ function exact(value, length) {
62
+ const decoded = unb64(value, length);
63
+ if (decoded.length !== length)
64
+ throw new Error("Invalid relay field length");
65
+ return decoded;
66
+ }
67
+ async function macKey(secret) {
68
+ if (!/^[\w-]{43,256}$/.test(secret))
69
+ throw new Error("Relay authentication key must be random base64url");
70
+ return crypto.subtle.importKey("raw", bytes(unb64(secret, 192)), { name: "HMAC", hash: "SHA-256" }, false, ["sign", "verify"]);
71
+ }
72
+ async function publicKey(jwk) {
73
+ if (jwk?.kty !== "EC" || jwk.crv !== "P-256" || jwk.d !== undefined)
74
+ throw new Error("Relay requires a public P-256 key");
75
+ return crypto.subtle.importKey("jwk", jwk, { name: "ECDH", namedCurve: "P-256" }, false, []);
76
+ }
77
+ async function keys(privateKey, publicKey, salt) {
78
+ const shared = await crypto.subtle.deriveBits({ name: "ECDH", public: publicKey }, privateKey, 256);
79
+ const material = await crypto.subtle.importKey("raw", shared, "HKDF", false, ["deriveKey"]);
80
+ const derive = (direction) => crypto.subtle.deriveKey({
81
+ name: "HKDF",
82
+ hash: "SHA-256",
83
+ salt: bytes(salt),
84
+ info: bytes(encoder.encode(`edgeshield-relay:v1:${direction}`)),
85
+ }, material, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
86
+ return { request: await derive("request"), response: await derive("response") };
87
+ }
88
+ function headers(input) {
89
+ return [...input]
90
+ .filter(([key]) => key !== "set-cookie")
91
+ .concat(input.getSetCookie().map((value) => ["set-cookie", value]));
92
+ }
93
+ export async function createRelayTransport(options) {
94
+ const endpoint = new URL(options.endpoint);
95
+ if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.hash)
96
+ throw new Error("Relay requires an exact HTTPS endpoint");
97
+ const server = await publicKey(options.serverPublicKey), authentication = await macKey(options.authenticationKey), limit = bodyLimit(options.maxBytes), transport = options.fetch ?? fetch, now = options.now ?? Date.now;
98
+ return async (input, init) => {
99
+ const request = new Request(input, init), target = new URL(request.url);
100
+ if (target.origin !== "https://origin.internal")
101
+ throw new Error("Relay target is outside the private business origin");
102
+ const pair = await crypto.subtle.generateKey({ name: "ECDH", namedCurve: "P-256" }, true, [
103
+ "deriveBits",
104
+ ]);
105
+ const salt = crypto.getRandomValues(new Uint8Array(32)), session = await keys(pair.privateKey, server, salt);
106
+ const meta = {
107
+ v: 1,
108
+ id: crypto.randomUUID(),
109
+ at: now(),
110
+ epk: await crypto.subtle.exportKey("jwk", pair.publicKey),
111
+ salt: b64(salt),
112
+ };
113
+ const aad = encoder.encode(stableJson(meta)), nonce = crypto.getRandomValues(new Uint8Array(12));
114
+ const plain = encoder.encode(JSON.stringify({
115
+ method: request.method,
116
+ target: target.pathname + target.search,
117
+ headers: headers(request.headers),
118
+ body: b64(await readBytes(request, limit)),
119
+ }));
120
+ if (plain.length > limit * 2 + 65536)
121
+ throw new Error("Relay payload exceeds limit");
122
+ const ciphertext = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv: bytes(nonce), additionalData: bytes(aad) }, session.request, bytes(plain)));
123
+ const packet = { ...meta, nonce: b64(nonce), body: b64(ciphertext) };
124
+ const signature = b64(new Uint8Array(await crypto.subtle.sign("HMAC", authentication, bytes(encoder.encode(stableJson(packet))))));
125
+ const response = await transport(endpoint, {
126
+ method: "POST",
127
+ redirect: "manual",
128
+ signal: request.signal,
129
+ headers: { "content-type": "application/vnd.edgeshield.relay+json" },
130
+ body: JSON.stringify({ ...packet, signature }),
131
+ });
132
+ if (!response.ok)
133
+ throw new Error(`Relay endpoint rejected request (${response.status})`);
134
+ const envelope = JSON.parse(decoder.decode(await readBytes(response, limit * 3 + 262144)));
135
+ if (envelope.v !== 1 || envelope.id !== meta.id)
136
+ throw new Error("Relay response binding mismatch");
137
+ const decoded = await crypto.subtle.decrypt({
138
+ name: "AES-GCM",
139
+ iv: bytes(exact(envelope.nonce, 12)),
140
+ additionalData: bytes(encoder.encode(stableJson({ v: 1, id: meta.id, direction: "response" }))),
141
+ }, session.response, bytes(unb64(envelope.body, limit * 2 + 65536)));
142
+ const result = JSON.parse(decoder.decode(decoded));
143
+ if (!Number.isInteger(result.status) ||
144
+ result.status < 200 ||
145
+ result.status > 599 ||
146
+ !Array.isArray(result.headers))
147
+ throw new Error("Invalid relay response");
148
+ const body = unb64(result.body, limit);
149
+ return new Response(request.method === "HEAD" || [204, 205, 304].includes(result.status)
150
+ ? null
151
+ : body, { status: result.status, headers: result.headers });
152
+ };
153
+ }
154
+ export async function createRelayServer(options) {
155
+ const privateKey = await crypto.subtle.importKey("jwk", options.serverPrivateKey, { name: "ECDH", namedCurve: "P-256" }, false, ["deriveBits"]), authentication = await macKey(options.authenticationKey), limit = bodyLimit(options.maxBytes), now = options.now ?? Date.now;
156
+ return async (request) => {
157
+ try {
158
+ if (request.method !== "POST")
159
+ return new Response(null, { status: 405 });
160
+ const packet = JSON.parse(decoder.decode(await readBytes(request, limit * 3 + 262144)));
161
+ const { signature, ...signed } = packet;
162
+ if (packet.v !== 1 ||
163
+ typeof packet.id !== "string" ||
164
+ !/^[a-f\d-]{36}$/i.test(packet.id) ||
165
+ !Number.isSafeInteger(packet.at) ||
166
+ Math.abs(now() - packet.at) > 30000 ||
167
+ Object.keys(packet).some((key) => !["v", "id", "at", "epk", "salt", "nonce", "body", "signature"].includes(key)))
168
+ throw new Error("Invalid relay envelope");
169
+ if (!(await crypto.subtle.verify("HMAC", authentication, bytes(exact(signature, 32)), bytes(encoder.encode(stableJson(signed))))))
170
+ throw new Error("Relay authentication failed");
171
+ if (!(await options.replay.claim(packet.id, packet.at + 60000)))
172
+ throw new Error("Relay request replayed");
173
+ const meta = { v: 1, id: packet.id, at: packet.at, epk: packet.epk, salt: packet.salt }, session = await keys(privateKey, await publicKey(packet.epk), exact(packet.salt, 32));
174
+ const plain = await crypto.subtle.decrypt({
175
+ name: "AES-GCM",
176
+ iv: bytes(exact(packet.nonce, 12)),
177
+ additionalData: bytes(encoder.encode(stableJson(meta))),
178
+ }, session.request, bytes(unb64(packet.body, limit * 2 + 65536)));
179
+ const decoded = JSON.parse(decoder.decode(plain));
180
+ if (typeof decoded.method !== "string" ||
181
+ !["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"].includes(decoded.method) ||
182
+ typeof decoded.target !== "string" ||
183
+ !decoded.target.startsWith("/") ||
184
+ decoded.target.startsWith("//") ||
185
+ /[\r\n#]/.test(decoded.target) ||
186
+ !Array.isArray(decoded.headers) ||
187
+ decoded.headers.length > 128)
188
+ throw new Error("Invalid relay request target");
189
+ const target = new URL(decoded.target, "https://origin.internal");
190
+ if (target.origin !== "https://origin.internal")
191
+ throw new Error("Invalid relay authority");
192
+ const payload = unb64(decoded.body, limit), requestHeaders = new Headers(decoded.headers);
193
+ const expected = await crypto.subtle.digest("SHA-256", bytes(encoder.encode(options.originToken))), provided = await crypto.subtle.digest("SHA-256", bytes(encoder.encode(requestHeaders.get("x-shield-origin-auth") ?? "")));
194
+ if (b64(new Uint8Array(expected)) !== b64(new Uint8Array(provided)))
195
+ throw new Error("Untrusted relay origin credential");
196
+ const response = await options.business(new Request(target, {
197
+ method: decoded.method,
198
+ headers: requestHeaders,
199
+ ...(!["GET", "HEAD"].includes(decoded.method) && payload.length
200
+ ? { body: payload }
201
+ : {}),
202
+ }));
203
+ const body = encoder.encode(JSON.stringify({
204
+ status: response.status,
205
+ headers: headers(response.headers),
206
+ body: b64(await readBytes(response, limit)),
207
+ }));
208
+ const nonce = crypto.getRandomValues(new Uint8Array(12));
209
+ const cipher = await crypto.subtle.encrypt({
210
+ name: "AES-GCM",
211
+ iv: bytes(nonce),
212
+ additionalData: bytes(encoder.encode(stableJson({ v: 1, id: packet.id, direction: "response" }))),
213
+ }, session.response, bytes(body));
214
+ return Response.json({ v: 1, id: packet.id, nonce: b64(nonce), body: b64(new Uint8Array(cipher)) }, { headers: { "cache-control": "no-store" } });
215
+ }
216
+ catch {
217
+ return Response.json({ error: "relay_request_rejected" }, { status: 403, headers: { "cache-control": "no-store" } });
218
+ }
219
+ };
220
+ }
221
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../../../scr/origin/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare class SqliteReplayStore {
2
+ private capacity;
3
+ private now;
4
+ private database;
5
+ constructor(path: string, capacity?: number, now?: () => number);
6
+ claim(id: string, expiresAt: number): Promise<boolean>;
7
+ close(): void;
8
+ }
@@ -0,0 +1,36 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ export class SqliteReplayStore {
3
+ capacity;
4
+ now;
5
+ database;
6
+ constructor(path, capacity = 4096, now = Date.now) {
7
+ this.capacity = capacity;
8
+ this.now = now;
9
+ this.database = new DatabaseSync(path);
10
+ this.database.exec("PRAGMA journal_mode=WAL; CREATE TABLE IF NOT EXISTS replay (id TEXT PRIMARY KEY, expires INTEGER NOT NULL); CREATE INDEX IF NOT EXISTS expiry ON replay(expires)");
11
+ }
12
+ async claim(id, expiresAt) {
13
+ this.database.exec("BEGIN IMMEDIATE");
14
+ try {
15
+ this.database.prepare("DELETE FROM replay WHERE expires <= ?").run(this.now());
16
+ if (this.database.prepare("SELECT id FROM replay WHERE id=?").get(id)) {
17
+ this.database.exec("COMMIT");
18
+ return false;
19
+ }
20
+ const count = this.database.prepare("SELECT count(*) AS n FROM replay").get();
21
+ if (count.n >= this.capacity)
22
+ throw new Error("Relay replay store capacity exceeded");
23
+ this.database.prepare("INSERT INTO replay VALUES (?,?)").run(id, expiresAt);
24
+ this.database.exec("COMMIT");
25
+ return true;
26
+ }
27
+ catch (error) {
28
+ this.database.exec("ROLLBACK");
29
+ throw error;
30
+ }
31
+ }
32
+ close() {
33
+ this.database.close();
34
+ }
35
+ }
36
+ //# sourceMappingURL=replay-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-node.js","sourceRoot":"","sources":["../../../../scr/origin/replay-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,MAAM,OAAO,iBAAiB;IAIlB,QAAQ;IACR,GAAG;IAJL,QAAQ,CAAe;IAC/B,YACE,IAAY,EACJ,QAAQ,GAAG,IAAI,EACf,GAAG,GAAG,IAAI,CAAC,GAAG;wBADd,QAAQ;mBACR,GAAG;QAEX,IAAI,CAAC,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,kKAAkK,CACnK,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,EAAU,EAAE,SAAiB;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/E,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,GAAG,EAE1E,CAAC;YACF,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACtF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5E,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}