@goodandready/dsh-usage-guard 0.1.15 → 0.1.16
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/lib/index.js +0 -2
- package/lib/telemetry.js +103 -3
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -156,8 +156,6 @@ export function apply(ctx, config) {
|
|
|
156
156
|
badFields: bad,
|
|
157
157
|
fixedTokenCount: fixedTokensCount,
|
|
158
158
|
clamped: clampedAny,
|
|
159
|
-
provider: event?.provider ?? event?.data?.provider ?? 'unknown',
|
|
160
|
-
sample: found.usage,
|
|
161
159
|
})
|
|
162
160
|
|
|
163
161
|
if (live && live.report !== false) {
|
package/lib/telemetry.js
CHANGED
|
@@ -11,7 +11,7 @@ class UsageGuardTelemetry {
|
|
|
11
11
|
this.recentIncidents = [];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
recordIncident({ turn = 0, step = 0, badFields = [], fixedTokenCount = 0, clamped = false,
|
|
14
|
+
recordIncident({ turn = 0, step = 0, badFields = [], fixedTokenCount = 0, clamped = false, kind = 'malformed-usage', target = '' } = {}) {
|
|
15
15
|
this.rescuedEvents += 1;
|
|
16
16
|
this.fixedTokens += Number(fixedTokenCount) || 0;
|
|
17
17
|
if (clamped) {
|
|
@@ -26,8 +26,6 @@ class UsageGuardTelemetry {
|
|
|
26
26
|
target: String(target || (Array.isArray(badFields) ? badFields.join(',') : '')),
|
|
27
27
|
fields: Array.isArray(badFields) ? badFields : [],
|
|
28
28
|
clamped: Boolean(clamped),
|
|
29
|
-
provider: typeof provider === 'string' ? provider : 'unknown',
|
|
30
|
-
sample: sample && typeof sample === 'object' ? JSON.stringify(sample).slice(0, 300) : null,
|
|
31
29
|
};
|
|
32
30
|
|
|
33
31
|
this.lastIncident = incident;
|
|
@@ -89,6 +87,100 @@ export function resetTelemetry() {
|
|
|
89
87
|
telemetry.reset();
|
|
90
88
|
}
|
|
91
89
|
|
|
90
|
+
function header(request, name) {
|
|
91
|
+
const value = request?.headers?.[name.toLowerCase()];
|
|
92
|
+
return Array.isArray(value) ? value[0] : value;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isLoopbackAddress(value) {
|
|
96
|
+
const address = String(value || '').toLowerCase().replace(/^[[\]]/g, '');
|
|
97
|
+
return address === 'localhost' || address === 'localhost.' || address === '::1'
|
|
98
|
+
|| address.startsWith('127.')
|
|
99
|
+
|| address.startsWith('::ffff:127.');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Reject cross-site and unauthenticated requests while allowing same-origin and local callers. */
|
|
103
|
+
export function isTrustedSettingsRequest(request, options = {}) {
|
|
104
|
+
if (!request || typeof request !== 'object' || !request.headers) return false;
|
|
105
|
+
|
|
106
|
+
const secFetchSite = header(request, 'sec-fetch-site');
|
|
107
|
+
// Unconditionally reject cross-site requests
|
|
108
|
+
if (secFetchSite === 'cross-site') {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const host = header(request, 'x-forwarded-host') || header(request, 'host');
|
|
113
|
+
const origin = header(request, 'origin');
|
|
114
|
+
if (origin) {
|
|
115
|
+
try {
|
|
116
|
+
const url = new URL(origin);
|
|
117
|
+
if (host && url.host.toLowerCase() === host.toLowerCase()) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
if (isLoopbackAddress(url.hostname) && isLoopbackAddress(request?.socket?.remoteAddress)) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
} catch {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const referer = header(request, 'referer');
|
|
130
|
+
if (referer) {
|
|
131
|
+
try {
|
|
132
|
+
const url = new URL(referer);
|
|
133
|
+
if (host && url.host.toLowerCase() === host.toLowerCase()) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
if (isLoopbackAddress(url.hostname) && isLoopbackAddress(request?.socket?.remoteAddress)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
} catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Check Bearer token or custom auth header
|
|
146
|
+
const expectedToken = options.expectedToken
|
|
147
|
+
|| (typeof process !== 'undefined' ? (process.env?.DSH_AUTH_TOKEN || process.env?.DSH_TOKEN) : null);
|
|
148
|
+
|
|
149
|
+
const auth = header(request, 'authorization');
|
|
150
|
+
if (typeof auth === 'string' && auth.startsWith('Bearer ')) {
|
|
151
|
+
const bearer = auth.slice(7).trim();
|
|
152
|
+
if (expectedToken && bearer && bearer === expectedToken) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const customAuth = header(request, 'x-dsh-auth');
|
|
158
|
+
if (expectedToken && customAuth && customAuth === expectedToken) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Check cookie authentication
|
|
163
|
+
const cookie = header(request, 'cookie');
|
|
164
|
+
if (typeof cookie === 'string' && expectedToken) {
|
|
165
|
+
const match = cookie.match(/(?:^|;\s*)(?:token|dsh-auth|dsh_token)=([^;]+)/);
|
|
166
|
+
if (match && match[1] === expectedToken) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Same-origin or same-site fetch
|
|
172
|
+
if (secFetchSite === 'same-origin' || secFetchSite === 'same-site') {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Loopback connection (curl, local process)
|
|
177
|
+
if (isLoopbackAddress(request?.socket?.remoteAddress)) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
|
|
92
184
|
export function registerTelemetryRoute(ctx, options = {}) {
|
|
93
185
|
const endpoint = options.endpoint || '/api/dsh-usage-guard/telemetry';
|
|
94
186
|
return ctx.webServer.register({
|
|
@@ -100,6 +192,14 @@ export function registerTelemetryRoute(ctx, options = {}) {
|
|
|
100
192
|
response.end();
|
|
101
193
|
return;
|
|
102
194
|
}
|
|
195
|
+
if (!isTrustedSettingsRequest(request, options)) {
|
|
196
|
+
response.writeHead(403, {
|
|
197
|
+
'content-type': 'application/json; charset=utf-8',
|
|
198
|
+
'cache-control': 'no-store',
|
|
199
|
+
});
|
|
200
|
+
response.end(request.method === 'HEAD' ? undefined : JSON.stringify({ error: 'Forbidden: untrusted or cross-site request' }));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
103
203
|
const snapshot = telemetry.getSnapshot();
|
|
104
204
|
response.writeHead(200, {
|
|
105
205
|
'content-type': 'application/json; charset=utf-8',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-usage-guard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Keeps a malformed token-usage sample from taking a whole session history down with it: a missing or non-numeric counter becomes zero before the harness adds it up, so the fold never yields NaN and already-broken sessions open again.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|