Skip to content

Commit 9fa3e2c

Browse files
authored
Merge pull request #398 from bugdrophq/codex/fix-admin-request-logging
fix: keep encoded admin requests out of URL logs
2 parents 8c0d2b3 + c993b79 commit 9fa3e2c

5 files changed

Lines changed: 30 additions & 6 deletions

File tree

docs/protocol/cross-plane-safety.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
The current public system remains supported. This harness compares its tracked
44
runtime, assets, widget build inputs and Wrangler configuration to the reviewed
5-
`test/cross-plane/fixtures/current-public-baseline.v2.json`. V1 remains the
5+
`test/cross-plane/fixtures/current-public-baseline.v3.json`. V1 remains the
66
pre-admin-read historical record. V2 is an intentional public-plane change:
77
the protected inventory route, read-only Durable Object deletion check, and
8-
admin URL-log exclusion. The change was independently reviewed, and the new
9-
inventory and legacy count paths have targeted regression tests. This baseline
8+
admin URL-log exclusion. V3 corrects that exclusion to use Hono's decoded routing
9+
path, so percent-encoded aliases of the admin route do not leak query strings to
10+
the global request logger. The change was independently reviewed, and a regression
11+
test fails against V2 and passes against V3. This baseline
1012
update does not itself authorize deployment or a change to public delivery.
1113
Public fingerprint mutations and changed/skipped/retried browser evidence must fail.
1214
An intentional future public change requires explicit baseline review; do not

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ app.use('*', async (c, next) => {
5151
// including malformed query strings, out of URL logs.
5252
const requestLogger = logger();
5353
app.use('*', (c, next) => {
54-
const path = new URL(c.req.url).pathname;
54+
// Use Hono's decoded path so aliases that reach this route cannot bypass the log exclusion.
55+
const path = c.req.path;
5556
if (path === '/internal/admin' || path.startsWith('/internal/admin/')) return next();
5657
return requestLogger(c, next);
5758
});

test/adminInstallations.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,21 @@ describe('server-only administrator installation inventory', () => {
147147
env,
148148
{} as ExecutionContext
149149
);
150+
await mounted.fetch(
151+
new Request(
152+
'https://worker.example/intern%61l/admin/installations?cursor=accidental-secret',
153+
{ headers: { Authorization: `Bearer ${SECRET}` } }
154+
),
155+
env,
156+
{} as ExecutionContext
157+
);
150158
expect(logs).not.toHaveBeenCalled();
159+
await mounted.fetch(
160+
new Request('https://worker.example/api/health'),
161+
env,
162+
{} as ExecutionContext
163+
);
164+
expect(logs).toHaveBeenCalled();
151165
} finally {
152166
logs.mockRestore();
153167
}

test/cross-plane/current-public.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
22
import { execFileSync } from 'node:child_process';
33
import { readFileSync } from 'node:fs';
44
import { describe, expect, it } from 'vitest';
5-
import baseline from './fixtures/current-public-baseline.v2.json';
5+
import baseline from './fixtures/current-public-baseline.v3.json';
66

77
function publicFiles(): string[] {
88
return execFileSync('git', ['ls-files', '-z'], { encoding: 'utf8' })
@@ -22,7 +22,7 @@ function fingerprint(paths: string[], read: (path: string) => Uint8Array): strin
2222
return hash.digest('hex');
2323
}
2424

25-
describe('current public plane matches the reviewed admin-read baseline', () => {
25+
describe('current public plane matches the reviewed admin URL-log baseline', () => {
2626
it('matches the reviewed tracked runtime, assets and configuration byte for byte', () => {
2727
const paths = publicFiles();
2828
expect(paths.length).toBe(baseline.fileCount);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"schemaVersion": 3,
3+
"baseCommit": "8c0d2b34d78a2a260513268112c5413e2d4d9d43",
4+
"description": "Reviewed public-plane change aligning the admin URL-log exclusion with Hono's decoded routing path. SHA-256 of sorted tracked path + NUL + exact bytes + NUL; V2 remains the pre-fix record.",
5+
"fileCount": 146,
6+
"sha256": "aea765d5ecf2b93e83cae1733a11f60271c045016ef44e9dcbe7d646ebe212bb"
7+
}

0 commit comments

Comments
 (0)