dsh-permission-rules 0.6.3 → 0.6.4
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 +10 -0
- package/lib/index.js +17 -11
- package/lib/types/proxy.d.ts.map +1 -1
- package/lib/types/runtime.d.ts +1 -1
- package/package.json +19 -19
- package/src/proxy.ts +22 -10
- package/src/runtime.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to dsh-permission-rules are recorded here, newest first.
|
|
4
4
|
|
|
5
|
+
## v0.6.4 — 2026-09-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Guard every CONNECT socket error window so a client reset can no longer
|
|
10
|
+
crash the host process: the raw tunnel socket now gets an explicit `error`
|
|
11
|
+
handler (log + destroy both peers) before any await or write, covering the
|
|
12
|
+
decision await, the 400 early return, and the 403 early return paths
|
|
13
|
+
([#12](https://github.com/PerryLink/dsh-permission-rules/issues/12)).
|
|
14
|
+
|
|
5
15
|
## v0.6.3 — 2026-08-30
|
|
6
16
|
|
|
7
17
|
### Fixed
|
package/lib/index.js
CHANGED
|
@@ -2138,6 +2138,12 @@ var NetworkProxy = class {
|
|
|
2138
2138
|
}
|
|
2139
2139
|
/** CONNECT tunneling (HTTPS and friends): adjudicate, then either 403 or an established TCP tunnel. */
|
|
2140
2140
|
async handleConnect(req, socket, head) {
|
|
2141
|
+
const tunnelHolder = {};
|
|
2142
|
+
socket.on("error", (error) => {
|
|
2143
|
+
this.options.logger.warn(`permission-rules: CONNECT socket error: ${String(error)}`);
|
|
2144
|
+
tunnelHolder.tunnel?.destroy();
|
|
2145
|
+
socket.destroy();
|
|
2146
|
+
});
|
|
2141
2147
|
const target = connectTarget(req.url ?? "");
|
|
2142
2148
|
if (target === void 0) {
|
|
2143
2149
|
socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
|
|
@@ -2150,22 +2156,22 @@ var NetworkProxy = class {
|
|
|
2150
2156
|
socket.end(`HTTP/1.1 403 Forbidden\r\ncontent-type: text/plain\r\ncontent-length: ${Buffer.byteLength(body)}\r\n\r\n${body}`);
|
|
2151
2157
|
return;
|
|
2152
2158
|
}
|
|
2153
|
-
const
|
|
2159
|
+
const tunnel = connect(target.port ?? 443, target.host);
|
|
2160
|
+
tunnelHolder.tunnel = tunnel;
|
|
2154
2161
|
this.sockets.add(socket);
|
|
2155
|
-
this.sockets.add(
|
|
2162
|
+
this.sockets.add(tunnel);
|
|
2156
2163
|
const cleanup = () => {
|
|
2157
2164
|
this.sockets.delete(socket);
|
|
2158
|
-
this.sockets.delete(
|
|
2165
|
+
this.sockets.delete(tunnel);
|
|
2159
2166
|
};
|
|
2160
2167
|
socket.on("close", cleanup);
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
upstream.once("connect", () => {
|
|
2168
|
+
tunnel.on("close", cleanup);
|
|
2169
|
+
tunnel.on("error", () => socket.destroy());
|
|
2170
|
+
tunnel.once("connect", () => {
|
|
2165
2171
|
socket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
2166
|
-
if (head.length > 0)
|
|
2167
|
-
|
|
2168
|
-
socket.pipe(
|
|
2172
|
+
if (head.length > 0) tunnel.write(head);
|
|
2173
|
+
tunnel.pipe(socket);
|
|
2174
|
+
socket.pipe(tunnel);
|
|
2169
2175
|
});
|
|
2170
2176
|
}
|
|
2171
2177
|
/** Adjudicate one plain-HTTP request; deny/ask blocks with a structured 403 before any forwarding. */
|
|
@@ -3674,7 +3680,7 @@ async function apply(ctx, config) {
|
|
|
3674
3680
|
* whole alpha line is treated as unsafe; over-refusal is harmless because
|
|
3675
3681
|
* `allowUnmarkedAudit: true` opts back in, and
|
|
3676
3682
|
* `scripts/repair-session-logs.mjs strip` removes already-written audit
|
|
3677
|
-
* rows for hosts where the marker cannot help. Extend the bound if a
|
|
3683
|
+
* rows for hosts where the marker cannot help. On 0.1.2-alpha.2 the envelope field is restored for stored-log read compatibility only - its Session.append still cannot stamp the marker, so the gate behavior is unchanged. Extend the bound if a
|
|
3678
3684
|
* future alpha/rc line regresses. Non-matching (later rc, stable, or
|
|
3679
3685
|
* unresolvable) versions are treated as possibly-marker-aware and
|
|
3680
3686
|
* verified by the append probe.
|
package/lib/types/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"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"}
|
package/lib/types/runtime.d.ts
CHANGED
|
@@ -425,7 +425,7 @@ export declare function apply(ctx: Context, config: Config): Promise<void>;
|
|
|
425
425
|
* whole alpha line is treated as unsafe; over-refusal is harmless because
|
|
426
426
|
* `allowUnmarkedAudit: true` opts back in, and
|
|
427
427
|
* `scripts/repair-session-logs.mjs strip` removes already-written audit
|
|
428
|
-
* rows for hosts where the marker cannot help. Extend the bound if a
|
|
428
|
+
* rows for hosts where the marker cannot help. On 0.1.2-alpha.2 the envelope field is restored for stored-log read compatibility only - its Session.append still cannot stamp the marker, so the gate behavior is unchanged. Extend the bound if a
|
|
429
429
|
* future alpha/rc line regresses. Non-matching (later rc, stable, or
|
|
430
430
|
* unresolvable) versions are treated as possibly-marker-aware and
|
|
431
431
|
* verified by the append probe.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-permission-rules",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Declarative Claude Code-style permission rules plus a Codex-style process-level network policy for DeepSeek Harness: ordered allow/deny/ask rules with tool-name, argument (glob/regex), workspace-path, and network-target (domain/ip/port/scheme) matching on the tools/pre-execute waterfall, a built-in local HTTP/CONNECT proxy governing shell subprocess traffic, three network modes mapped onto the official sandbox presets, full session-log audit, HMR rule reload, and a settings page with a rule editor, block counters, and recent interception lists.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
],
|
|
78
78
|
"compatibility": {
|
|
79
79
|
"dshVersions": [
|
|
80
|
-
"0.1.
|
|
80
|
+
"0.1.2-alpha.2"
|
|
81
81
|
]
|
|
82
82
|
},
|
|
83
83
|
"capability": {
|
|
@@ -155,26 +155,26 @@
|
|
|
155
155
|
"yaml": "^2.8.0",
|
|
156
156
|
"zod": "^4.4.3"
|
|
157
157
|
},
|
|
158
|
-
"devDependencies": {
|
|
158
|
+
"devDependencies": {"@deepseek-ai/dsh-attachment": "0.1.2-alpha.2",
|
|
159
159
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
160
160
|
"@deepseek-ai/cordis-plugin-include": "1.0.6",
|
|
161
161
|
"@deepseek-ai/cordis-plugin-loader": "1.0.2",
|
|
162
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
163
|
-
"@deepseek-ai/dsh-brand": "0.1.
|
|
164
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
165
|
-
"@deepseek-ai/dsh-client-locale": "0.1.
|
|
166
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.
|
|
167
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
168
|
-
"@deepseek-ai/dsh-client-web": "0.1.
|
|
169
|
-
"@deepseek-ai/dsh-commands": "0.1.
|
|
170
|
-
"@deepseek-ai/dsh-invariants": "0.1.
|
|
171
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
172
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
173
|
-
"@deepseek-ai/dsh-session-projection": "0.1.
|
|
174
|
-
"@deepseek-ai/dsh-subagent": "0.1.
|
|
175
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
176
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.
|
|
177
|
-
"@deepseek-ai/dsh-user-approval": "0.1.
|
|
162
|
+
"@deepseek-ai/dsh-agent": "0.1.2-alpha.2",
|
|
163
|
+
"@deepseek-ai/dsh-brand": "0.1.2-alpha.2",
|
|
164
|
+
"@deepseek-ai/dsh-client-connection": "0.1.2-alpha.2",
|
|
165
|
+
"@deepseek-ai/dsh-client-locale": "0.1.2-alpha.2",
|
|
166
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.2",
|
|
167
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.2",
|
|
168
|
+
"@deepseek-ai/dsh-client-web": "0.1.2-alpha.2",
|
|
169
|
+
"@deepseek-ai/dsh-commands": "0.1.2-alpha.2",
|
|
170
|
+
"@deepseek-ai/dsh-invariants": "0.1.2-alpha.2",
|
|
171
|
+
"@deepseek-ai/dsh-llm": "0.1.2-alpha.2",
|
|
172
|
+
"@deepseek-ai/dsh-session": "0.1.2-alpha.2",
|
|
173
|
+
"@deepseek-ai/dsh-session-projection": "0.1.2-alpha.2",
|
|
174
|
+
"@deepseek-ai/dsh-subagent": "0.1.2-alpha.2",
|
|
175
|
+
"@deepseek-ai/dsh-tools": "0.1.2-alpha.2",
|
|
176
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.2-alpha.2",
|
|
177
|
+
"@deepseek-ai/dsh-user-approval": "0.1.2-alpha.2",
|
|
178
178
|
"@deepseek-ai/schemastery": "^3.18.0",
|
|
179
179
|
"@eslint/js": "^10.0.1",
|
|
180
180
|
"@types/node": "^22.19.0",
|
package/src/proxy.ts
CHANGED
|
@@ -184,6 +184,18 @@ export class NetworkProxy {
|
|
|
184
184
|
|
|
185
185
|
/** CONNECT tunneling (HTTPS and friends): adjudicate, then either 403 or an established TCP tunnel. */
|
|
186
186
|
private async handleConnect(req: IncomingMessage, socket: Duplex, head: Buffer): Promise<void> {
|
|
187
|
+
// Guard first (issue #12): a CONNECT socket is a raw Duplex handed over
|
|
188
|
+
// by the HTTP server with no default 'error' handling, so a client reset
|
|
189
|
+
// in any window — the decision await, the 400 early return, or the 403
|
|
190
|
+
// early return — would emit an unhandled 'error' and crash the host
|
|
191
|
+
// process. The handler closes over the tunnel holder so the same guard
|
|
192
|
+
// doubles as tunnel teardown once an upstream exists.
|
|
193
|
+
const tunnelHolder: { tunnel?: Duplex } = {}
|
|
194
|
+
socket.on('error', (error: unknown) => {
|
|
195
|
+
this.options.logger.warn(`permission-rules: CONNECT socket error: ${String(error)}`)
|
|
196
|
+
tunnelHolder.tunnel?.destroy()
|
|
197
|
+
socket.destroy()
|
|
198
|
+
})
|
|
187
199
|
const target = connectTarget(req.url ?? '')
|
|
188
200
|
if (target === undefined) {
|
|
189
201
|
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n')
|
|
@@ -196,22 +208,22 @@ export class NetworkProxy {
|
|
|
196
208
|
socket.end(`HTTP/1.1 403 Forbidden\r\ncontent-type: text/plain\r\ncontent-length: ${Buffer.byteLength(body)}\r\n\r\n${body}`)
|
|
197
209
|
return
|
|
198
210
|
}
|
|
199
|
-
const
|
|
211
|
+
const tunnel = connect(target.port ?? 443, target.host)
|
|
212
|
+
tunnelHolder.tunnel = tunnel
|
|
200
213
|
this.sockets.add(socket)
|
|
201
|
-
this.sockets.add(
|
|
214
|
+
this.sockets.add(tunnel)
|
|
202
215
|
const cleanup = (): void => {
|
|
203
216
|
this.sockets.delete(socket)
|
|
204
|
-
this.sockets.delete(
|
|
217
|
+
this.sockets.delete(tunnel)
|
|
205
218
|
}
|
|
206
219
|
socket.on('close', cleanup)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
upstream.once('connect', () => {
|
|
220
|
+
tunnel.on('close', cleanup)
|
|
221
|
+
tunnel.on('error', () => socket.destroy())
|
|
222
|
+
tunnel.once('connect', () => {
|
|
211
223
|
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n')
|
|
212
|
-
if (head.length > 0)
|
|
213
|
-
|
|
214
|
-
socket.pipe(
|
|
224
|
+
if (head.length > 0) tunnel.write(head)
|
|
225
|
+
tunnel.pipe(socket)
|
|
226
|
+
socket.pipe(tunnel)
|
|
215
227
|
})
|
|
216
228
|
}
|
|
217
229
|
|
package/src/runtime.ts
CHANGED
|
@@ -1265,7 +1265,7 @@ export async function apply(ctx: Context, config: Config): Promise<void> {
|
|
|
1265
1265
|
* whole alpha line is treated as unsafe; over-refusal is harmless because
|
|
1266
1266
|
* `allowUnmarkedAudit: true` opts back in, and
|
|
1267
1267
|
* `scripts/repair-session-logs.mjs strip` removes already-written audit
|
|
1268
|
-
* rows for hosts where the marker cannot help. Extend the bound if a
|
|
1268
|
+
* rows for hosts where the marker cannot help. On 0.1.2-alpha.2 the envelope field is restored for stored-log read compatibility only - its Session.append still cannot stamp the marker, so the gate behavior is unchanged. Extend the bound if a
|
|
1269
1269
|
* future alpha/rc line regresses. Non-matching (later rc, stable, or
|
|
1270
1270
|
* unresolvable) versions are treated as possibly-marker-aware and
|
|
1271
1271
|
* verified by the append probe.
|