// SPDX-License-Identifier: GPL-2.0-or-later // Copyright (C) 2026 Bryan Joshua Pedini /** * PLAN §12 persona "Malicious user": attempts to bypass authentication, obtain information, * corrupt state or cause unsafe behaviour through every interface that exists (HTTP via * Playwright / curl / raw socket, the CLI, the shared SQLite file, the Docker socket). * * Every test asserts: the exact status/exit outcome; no token secret (or 12-char fragment of * one) in any response or log; no internal detail in HTTP bodies; exact audit rows; structurally * valid database (assertDbInvariants) and, where the attack must not change anything, a * byte-identical logical state (stateDigest). */ import { DatabaseSync } from 'node:sqlite'; import fs from 'node:fs'; import { test, expect, assertDbInvariants, expectCliFailure, expectCliSuccess, expectContainersResponse, expectErrorResponse, expectNoInternalDetails, fileDigest, goQuote, mapLimit, msToNanos, parseAuditOutput, parseLogs, parseTokenList, pollUntil, readOperations, readSchema, readToken, rfc3339ToNanos, shellQuote, tokenId, USAGE_TEXT, type HttpClient, type RawResult, type ServerHandle, } from '../../harness'; import { ENDPOINT, SQL_PAYLOADS, StateModel, TOKEN_CHARS, auditArgsOutcome, authOf, expectedAuditStdout, expectNoTokenFragments, nearMatches, onlyResponse, routeOf, stateDigest, } from '../../harness/personas'; /** Raw request bytes (UTF-8): request line, Host, given header lines, optional Connection: close. */ function req(lines: string[], { target = ENDPOINT, method = 'GET', version = 'HTTP/1.1', close = true, body }: { target?: string; method?: string; version?: string; close?: boolean; body?: string } = {}): Buffer { const all = [`${method} ${target} ${version}`, 'Host: localhost', ...lines]; if (body !== undefined) all.push(`Content-Length: ${Buffer.byteLength(body)}`); if (close) all.push('Connection: close'); return Buffer.from(all.join('\r\n') + '\r\n\r\n' + (body ?? ''), 'utf8'); } function raw(http: HttpClient, s: ServerHandle, data: Buffer | string, extra: { expectResponses?: number; timeoutMs?: number } = {}): Promise { return http.raw({ host: s.connectHost, port: s.port, data: typeof data === 'string' ? Buffer.from(data, 'utf8') : data, timeoutMs: 20_000, ...extra }); } test('token enumeration: 1500 random guesses, near-matches, case/whitespace/confusable mutations and inactive tokens — only the documented OWS trim authenticates, responses are indistinguishable', async ({ cli, startServer, http, secrets, rng }) => { test.setTimeout(120_000); const model = new StateModel(); for (let i = 0; i < 5; i++) model.add(await cli.tokenNew(`victim ${i}`), `victim ${i}`); for (let i = 0; i < 4; i++) { const t = model.add(await cli.tokenNew(`revoked ${i}`), `revoked ${i}`).token; await cli.tokenDelete(t); model.deactivate(t); } const server = await startServer({ logLevel: 'DEBUG' }); server.fakeDocker!.many(2); const lookup = (t: string) => model.lookup(t); const expectedClasses: string[] = []; await test.step('1500 random 43-character guesses, 24 concurrent (Playwright)', async () => { const guesses = Array.from({ length: 1500 }, () => rng.string(43, TOKEN_CHARS)); const res = await mapLimit(guesses, 24, (g) => http.get(server.url(), { token: g })); for (const r of res) expectErrorResponse(r, 401); expectedClasses.push(...guesses.map(() => 'unknown_token')); }); await test.step('near-match mutations of every active and inactive token (raw socket, UTF-8 bytes)', async () => { const cases: Array<{ kind: string; header: string }> = []; for (const t of model.all()) { for (const m of nearMatches(t, rng, 30)) if (!/[\r\n]/.test(m.value)) cases.push({ kind: m.kind, header: `Bearer ${m.value}` }); for (const v of [`bearer ${t}`, `BEARER ${t}`, ` Bearer ${t}`, `Bearer ${t}\t`, `Bearer ${t} `, `Bearer\u{a0}${t}`, `Bearer ${t}\u{200b}`, `B\u{435}arer ${t}`]) cases.push({ kind: 'scheme/whitespace', header: v }); } let oks = 0; await mapLimit(cases, 16, async (c) => { const exp = authOf([c.header], lookup); const r = onlyResponse(await raw(http, server, req([`Authorization: ${c.header}`])), c.kind); if (exp.cls === 'ok') { // documented: HTTP itself trims leading/trailing whitespace of the header value (RFC 9110) expectContainersResponse(r); model.audit(exp.token!); oks++; } else expectErrorResponse(r, 401); expectedClasses.push(exp.cls); }); expect(oks, 'only OWS-trimmed exact tokens of active tokens authenticated').toBe(cases.filter((c) => authOf([c.header], lookup).cls === 'ok').length); expect(cases.length).toBeGreaterThan(300); }); await test.step('inactive tokens hammered: 4 × 25 concurrent requests → 401 every time', async () => { const attempts = model.inactive().flatMap((t) => Array.from({ length: 25 }, () => t)); for (const r of await mapLimit(attempts, 20, (t) => http.get(server.url(), { token: t }))) expectErrorResponse(r, 401); expectedClasses.push(...attempts.map(() => 'inactive_token')); }); await test.step('unknown, inactive, malformed and missing credentials are indistinguishable to the client', async () => { const shape = (r: RawResult) => { const res = onlyResponse(r, 'shape'); return { status: res.status, headers: res.headers.filter(([k]) => k.toLowerCase() !== 'date'), body: res.bodyText }; }; const variants = [ req([`Authorization: Bearer ${rng.string(43, TOKEN_CHARS)}`]), req([`Authorization: Bearer ${model.inactive()[0]}`]), req(['Authorization: Basic Zm9vOmJhcg==']), req([]), req([`Authorization: Bearer ${model.active()[0]}`, `Authorization: Bearer ${model.active()[0]}`]), ]; const shapes = []; for (const v of variants) shapes.push(shape(await raw(http, server, v))); for (const s of shapes.slice(1)) expect(s).toEqual(shapes[0]); expectedClasses.push('unknown_token', 'inactive_token', 'bad_scheme', 'missing_header', 'multiple_headers'); }); // the legitimate users are unaffected for (const t of model.active()) { expect(expectContainersResponse(await http.get(server.url(), { token: t }))).toHaveLength(2); model.audit(t); expectedClasses.push('ok'); } expect((await server.stop()).exitCode).toBe(0); const logs = server.logs(); expect(logs.filter({ msg: 'authentication result' }).map((r) => r.attrs.result).sort(), 'every attempt was classified as the oracle predicts').toEqual([...expectedClasses].sort()); expect(logs.count({ level: ['WARN', 'ERROR'] })).toBe(0); expectNoTokenFragments(server.stderr, secrets, 'server log'); model.verifyDb(server.dbPath); }); interface InjectionCase { name: string; data: Buffer; /** Expected status of each response, in order; `go` marks responses produced by Go (not the app). */ responses: Array<{ status: number; go?: boolean }>; /** Tokens that must get one audit row each. */ audits: string[]; } test('header injection, smuggling, duplicate/conflicting/oversized headers and malformed HTTP syntax (raw socket)', async ({ cli, startServer, http, secrets }) => { test.setTimeout(90_000); const T = await cli.tokenNew('valid'); const U = await cli.tokenNew('other'); const I = await cli.tokenNew('revoked'); await cli.tokenDelete(I); const server = await startServer({ logLevel: 'DEBUG' }); server.fakeDocker!.many(1); const ok = { status: 200 }; const c401 = { status: 401 }; const go400 = { status: 400, go: true }; const cases: InjectionCase[] = [ { name: 'CR inside a value (attempted header split) → Go 400', data: req([`Authorization: Bearer junk\rAuthorization: Bearer ${T}`]), responses: [go400], audits: [] }, { name: 'bare LF inside a value becomes a second Authorization header → 401 multiple', data: req([`Authorization: Bearer junk\nAuthorization: Bearer ${T}`]), responses: [c401], audits: [] }, { name: 'obs-fold hides "Authorization:" inside X-A → 401 missing', data: req(['X-A: x', ` Authorization: Bearer ${T}`]), responses: [c401], audits: [] }, { name: 'NUL inside the Authorization value → Go 400', data: req([`Authorization: Bearer ${T}\x00`]), responses: [go400], audits: [] }, { name: 'NUL inside a header name → Go 400', data: req([`X-\x00: 1`, `Authorization: Bearer ${T}`]), responses: [go400], audits: [] }, { name: 'space before the colon → Go 400', data: req([`Authorization : Bearer ${T}`]), responses: [go400], audits: [] }, { name: 'valid + revoked under different name case → 401', data: req([`authorization: Bearer ${T}`, `AUTHORIZATION: Bearer ${I}`]), responses: [c401], audits: [] }, { name: 'two different valid tokens → 401', data: req([`Authorization: Bearer ${T}`, `Authorization: Bearer ${U}`]), responses: [c401], audits: [] }, { name: 'valid then empty Authorization → 401', data: req([`Authorization: Bearer ${T}`, 'Authorization:']), responses: [c401], audits: [] }, { name: 'Authorization only in a chunked trailer → 401 missing', data: Buffer.from(`GET ${ENDPOINT} HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n1\r\na\r\n0\r\nAuthorization: Bearer ${T}\r\n\r\n`), responses: [c401], audits: [] }, { name: 'Authorization smuggled in a GET body → 401 missing', data: req([], { body: `Authorization: Bearer ${T}\r\n`, close: false }), responses: [c401], audits: [] }, { name: 'pipelined: valid, no auth, revoked on one connection → auth never carries over', data: Buffer.concat([req([`Authorization: Bearer ${T}`], { close: false }), req([], { close: false }), req([`Authorization: Bearer ${I}`])]), responses: [ok, c401, c401], audits: [T] }, { name: 'CL+TE request smuggling: the request after the chunk terminator is a separate, unauthenticated request', data: Buffer.from(`GET ${ENDPOINT} HTTP/1.1\r\nHost: x\r\nAuthorization: Bearer ${T}\r\nContent-Length: 4\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET ${ENDPOINT} HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n`), responses: [ok, c401], audits: [T], }, { name: 'PROXY protocol preamble spoofing the source → Go 400', data: Buffer.concat([Buffer.from('PROXY TCP4 6.6.6.6 127.0.0.1 1111 2222\r\n'), req([`Authorization: Bearer ${T}`])]), responses: [go400], audits: [] }, { name: 'foreign Host header → served normally', data: Buffer.from(`GET ${ENDPOINT} HTTP/1.1\r\nHost: evil.example:443\r\nAuthorization: Bearer ${T}\r\nConnection: close\r\n\r\n`), responses: [ok], audits: [T] }, { name: 'absolute-form target to another host with a valid token → same endpoint, 200', data: req([`Authorization: Bearer ${T}`], { target: `http://evil.example${ENDPOINT}` }), responses: [ok], audits: [T] }, { name: 'absolute-form target without credentials → 401', data: req([], { target: `http://evil.example${ENDPOINT}` }), responses: [c401], audits: [] }, { name: 'Expect: 100-continue with a body → final response only, authenticated', data: req([`Authorization: Bearer ${T}`, 'Expect: 100-continue'], { body: 'ab', close: false }), responses: [ok], audits: [T] }, { name: '1000 KiB extra header alongside a valid token (under the limit) → 200', data: req([`X-Pad: ${'p'.repeat(1000 * 1024)}`, `Authorization: Bearer ${T}`]), responses: [ok], audits: [T] }, { name: 'headers over the 1 MiB limit → Go 431, never audited', data: req([`Authorization: Bearer ${T}`, `X-Pad: ${'p'.repeat(1100 * 1024)}`]), responses: [{ status: 431, go: true }], audits: [] }, { name: '900 KiB bearer value → 401, value never logged', data: req([`Authorization: Bearer ${'Q'.repeat(900 * 1024)}`]), responses: [c401], audits: [] }, { name: '490 header lines + valid token → 200', data: req([...Array.from({ length: 490 }, (_, i) => `X-H${i}: v`), `Authorization: Bearer ${T}`]), responses: [ok], audits: [T] }, { name: '600 header lines (over Go\'s header count limit) → Go 431', data: req([`Authorization: Bearer ${T}`, ...Array.from({ length: 600 }, (_, i) => `X-H${i}: v`)]), responses: [{ status: 431, go: true }], audits: [] }, { name: 'HTTP/1.0 without Host → 200', data: Buffer.from(`GET ${ENDPOINT} HTTP/1.0\r\nAuthorization: Bearer ${T}\r\n\r\n`), responses: [ok], audits: [T] }, { name: 'HTTP/0.9-style request line → Go 400', data: Buffer.from(`GET ${ENDPOINT}\r\n\r\n`), responses: [go400], audits: [] }, { name: 'unsupported HTTP version → Go 505', data: req([`Authorization: Bearer ${T}`], { version: 'HTTP/9.9' }), responses: [{ status: 505, go: true }], audits: [] }, { name: 'lower-case method → 405 before authentication', data: req([`Authorization: Bearer ${T}`], { method: 'get' }), responses: [{ status: 405 }], audits: [] }, { name: 'method with a separator character → Go 400', data: req([`Authorization: Bearer ${T}`], { method: 'G(ET' }), responses: [go400], audits: [] }, { name: 'tab-separated request line → Go 400', data: Buffer.from(`GET\t${ENDPOINT}\tHTTP/1.1\r\nHost: x\r\nAuthorization: Bearer ${T}\r\n\r\n`), responses: [go400], audits: [] }, { name: 'missing request target → Go 400', data: Buffer.from(`GET HTTP/1.1\r\nHost: x\r\n\r\n`), responses: [go400], audits: [] }, { name: 'bare-LF line endings (tolerated by Go) → 200', data: Buffer.from(`GET ${ENDPOINT} HTTP/1.1\nHost: x\nAuthorization: Bearer ${T}\nConnection: close\n\n`), responses: [ok], audits: [T] }, { name: '64 KiB request target → 404', data: req([`Authorization: Bearer ${T}`], { target: '/' + 'z'.repeat(64 * 1024) }), responses: [{ status: 404 }], audits: [] }, { name: 'UTF-8 and Latin-1 bytes in unrelated header values → 200', data: Buffer.concat([Buffer.from(`GET ${ENDPOINT} HTTP/1.1\r\nHost: x\r\nX-U: \u{65e5}\u{672c}\r\nX-L: `), Buffer.from([0xe9, 0xff]), Buffer.from(`\r\nAuthorization: Bearer ${T}\r\nConnection: close\r\n\r\n`)]), responses: [ok], audits: [T] }, ]; const audited: string[] = []; let appResponses = 0; for (const c of cases) { await test.step(c.name, async () => { const r = await raw(http, server, c.data, { expectResponses: c.responses.length }); expect(r.outcome, c.name).toBe('response'); expect(r.responses.map((x) => x.status), c.name).toEqual(c.responses.map((x) => x.status)); r.responses.forEach((res, i) => { const e = c.responses[i]; if (e.go) expect(res.header('content-type'), `${c.name}: Go plain-text response`).toBe('text/plain; charset=utf-8'); else if (e.status === 200) expectContainersResponse(res); else expectErrorResponse(res, e.status as 401 | 404 | 405); if (!e.go) appResponses++; expectNoTokenFragments(res.bodyText + JSON.stringify(res.headers), secrets, `${c.name} response`); }); audited.push(...c.audits); }); } // the server survived everything expectContainersResponse(await http.get(server.url(), { token: U })); audited.push(U); expect((await server.stop()).exitCode).toBe(0); const logs = server.logs(); expect(logs.requests().length, 'Go-rejected requests never reach the app log').toBe(appResponses + 1); expect(readOperations(server.dbPath).map((o) => o.token), 'exactly the authenticated requests were audited, in order').toEqual(audited); expect(server.stderr).not.toContain('QQQQQQQQQQQQQQQQ'); expect(logs.count({ level: ['WARN', 'ERROR'] })).toBe(0); expectNoTokenFragments(server.stderr, secrets, 'server log'); assertDbInvariants(server.dbPath, { tokenCount: 3, operationCount: audited.length }); }); test('path normalization tricks and URL-encoding variations: only the exact endpoint after percent-decoding is served, nothing redirects', async ({ cli, startServer, http, secrets }) => { const T = await cli.tokenNew('paths'); const server = await startServer(); server.fakeDocker!.many(1); const targets: Array<[string, 200 | 404 | 400]> = [ [ENDPOINT, 200], ['/api/v1/%63ontainers', 200], ['/%61%70%69/%76%31/%63%6f%6e%74%61%69%6e%65%72%73', 200], ['/api/v1/containers?x=../../etc/passwd', 200], ['/api/v1/containers?%00', 200], ['/api/v1/containers?', 200], ['/api/v1/containers?a=%zz', 200], ['http://localhost/api/v1/containers', 200], ['http://evil.example:1/api/v1/containers?x=1', 200], ['/api/v1/containers/', 404], ['/api/v1/containers/.', 404], ['/api/v1/./containers', 404], ['/api/v1/x/../containers', 404], ['/api/v1/x/%2e%2e/containers', 404], ['/api/v1/x/%2E%2E%2Fcontainers', 404], ['/api/v1%2Fcontainers', 404], ['/api%2Fv1%2Fcontainers', 404], ['/api/v1/%2563ontainers', 404], ['/api/v1/%c0%aecontainers', 404], ['/api/v1/containers%00', 404], ['/api/v1/containers%3F', 404], ['/api/v1/containers%23', 404], ['/api/v1/containers;jsessionid=1', 404], ['/api/v1/containers..;/', 404], ['/api/v1/containers#frag', 404], ['//api/v1/containers', 404], ['/api//v1/containers', 404], ['/API/v1/containers', 404], ['/api/v1/CONTAINERS', 404], ['/api/v1/%43ontainers', 404], ['/api/v1/\u{ff43}ontainers', 404], ['/api/v1/%EF%BD%83ontainers', 404], ['/api\\v1\\containers', 404], ['/api/v1/containers\\', 404], ['/api/v1/containers%20', 404], ['/api/v1/containers.', 404], ['*', 404], ['/api/v1/%u0063ontainers', 400], ['/api/v1/containers%', 400], ['/api/v1/containers%zz', 400], ]; let audits = 0; let reached = 0; for (const [target, status] of targets) { await test.step(`${target} → ${status} (and 405 / 401 variants)`, async () => { if (target.startsWith('/')) expect(routeOf(target), 'the oracle agrees with the table').toBe(status === 200 ? 'endpoint' : status === 404 ? 'other' : 'bad'); const variants: Array<[string, Buffer, number]> = [ ['GET + token', req([`Authorization: Bearer ${T}`], { target }), status], ['POST + token', req([`Authorization: Bearer ${T}`], { target, method: 'POST' }), status === 200 ? 405 : status], ['GET, no token', req([], { target }), status === 200 ? 401 : status], ]; for (const [name, data, st] of variants) { const res = onlyResponse(await raw(http, server, data), `${target} ${name}`); expect(res.status, `${target} ${name}`).toBe(st); expect(res.header('location'), 'never redirected').toBeUndefined(); if (st === 400) expect(res.header('content-type')).toBe('text/plain; charset=utf-8'); else { reached++; if (st === 200) expectContainersResponse(res); else expectErrorResponse(res, st as 401 | 404 | 405); } if (st === 200) audits++; expectNoTokenFragments(res.bodyText, secrets, 'response'); } // curl --path-as-is agrees for targets curl can carry verbatim if (/^\/[A-Za-z0-9\-._~%/?=&;:@!$'()*+,]*$/.test(target) && !target.includes('%00') && status !== 400) { const c = await http.curl({ url: server.url(target), token: T, pathAsIs: true }); expect(c.exitCode).toBe(0); expect(c.status, `curl ${target}`).toBe(status); expect(c.headers['location']).toBeUndefined(); reached++; if (status === 200) audits++; } }); } expect((await server.stop()).exitCode).toBe(0); expect(server.logs().requests().length).toBe(reached); assertDbInvariants(server.dbPath, { tokenCount: 1, operationCount: audits }); }); test('SQL injection in every user-controlled field (descriptions, delete argument, bearer token, query): schema and rows intact, payloads stored verbatim', async ({ cli, ws, startServer, http, secrets }) => { test.setTimeout(90_000); const model = new StateModel(); const keep = model.add(await cli.tokenNew('keep'), 'keep').token; const revoked = model.add(await cli.tokenNew('revoked'), 'revoked').token; await cli.tokenDelete(revoked); model.deactivate(revoked); const attachTarget = ws.path('attached.db'); const payloads = [...SQL_PAYLOADS, `'; ATTACH DATABASE '${attachTarget}' AS x; CREATE TABLE x.t(a); --`, `${keep}' OR '1'='1`, `${keep}'--`, `' OR token LIKE '%`, `x'); UPDATE tokens SET active=1 WHERE token='${revoked}'; --`]; await test.step('descriptions: stored byte-exact, listed Go-quoted, nothing executed', async () => { for (const p of payloads) model.add(await cli.tokenNew(p), p); model.verifyDb(ws.dbPath); const rows = await cli.tokenList(); model.verifyList(rows); for (const p of payloads) expect(rows.some((r) => r.descriptionQuoted === goQuote(p)), `listed: ${p.slice(0, 40)}`).toBe(true); }); await test.step('delete argument: every payload is "token not found", state byte-identical', async () => { const before = stateDigest(ws.dbPath); for (const p of payloads) { const r = await cli.run(['token', 'delete', p]); expectCliFailure(r, { exitCode: 1, message: 'token not found' }); expect(r.stderr.includes(keep), 'token never echoed').toBe(false); } expect(stateDigest(ws.dbPath)).toBe(before); }); const server = await startServer({ logLevel: 'DEBUG' }); server.fakeDocker!.many(1); await test.step('bearer token and query string: unknown token, never a match', async () => { for (const p of payloads) { const r = onlyResponse(await raw(http, server, req([`Authorization: Bearer ${p}`])), p); expectErrorResponse(r, 401); expectNoTokenFragments(r.bodyText, secrets, 'response'); const q = await http.get(server.url(`${ENDPOINT}?token=${encodeURIComponent(p)}&filter=${encodeURIComponent(p)}`), { token: keep }); expectContainersResponse(q); model.audit(keep); } // the revoked token stays revoked despite the UPDATE payloads expectErrorResponse(await http.get(server.url(), { token: revoked }), 401); }); expect((await server.stop()).exitCode).toBe(0); const classes = server.logs().filter({ msg: 'authentication result' }).map((r) => r.attrs.result); expect(classes.filter((c) => c === 'unknown_token')).toHaveLength(payloads.length); expect(classes.filter((c) => c === 'inactive_token')).toHaveLength(1); expect(fs.existsSync(attachTarget), 'ATTACH payload was never executed').toBe(false); expect(readSchema(ws.dbPath).tables).toEqual(['operations', 'tokens']); expect(readToken(ws.dbPath, revoked)!.active).toBe(0); model.verifyDb(ws.dbPath, 'all payloads stored verbatim, no row altered'); }); test('shell metacharacters, control characters, log/list forging and Unicode confusables in descriptions; NUL where the platform permits it', async ({ cli, ws, startServer, http, secrets, rng }) => { test.setTimeout(90_000); const model = new StateModel(); const canary = ws.path('pwned'); const shellish = [`$(touch ${canary})`, `\`touch ${canary}\``, `; touch ${canary}`, `| touch ${canary}`, `&& touch ${canary}`, `\ntouch ${canary}`, `'; touch ${canary}; '`, `"; touch ${canary}; "`, `\${IFS}touch\${IFS}${canary}`]; const forging = [ 'x\ntime=2026-01-01T00:00:00.000Z level=ERROR msg="forged record" origin=6.6.6.6', '\r\nlevel=ERROR msg=forged', '" level=ERROR msg="forged', 'ok\x1b[2K\x1b[1Glevel=ERROR msg=forged\x1b[0m', 'a\tfalse\t2020-01-01T00:00:00Z\t2020-01-02T00:00:00Z', 'row\nFAKE.TOKEN\t""\ttrue\t2020-01-01T00:00:00Z\t-', // forging the padded table: a closing quote and padded columns inside the description 'a" false 2020-01-01T00:00:00Z 2020-01-02T00:00:00Z', '"' + ' '.repeat(40) + 'true 2020-01-01T00:00:00Z -', '\x08\x08\x08\x08\x7f\x07\x0c\x0b', 'tab\there\u{2028}ls\u{2029}ps\u{85}nel', ]; const confusables = ['\u{430}dmin', 'admin', 'p\u{430}yp\u{430}l', '\u{202e}lanimret\u{202c}', '\u{ff21}\u{ff24}\u{ff2d}\u{ff29}\u{ff2e}', 'e\u{301}', '\u{e9}']; await test.step('created through argv and through a real shell with quoting: stored verbatim, never executed', async () => { for (const d of [...shellish, ...forging, ...confusables]) model.add(await cli.tokenNew(d), d); for (const d of shellish) { const r = await cli.shell(`"$DPSAPI_BIN" token new ${shellQuote(d)}`); expectCliSuccess(r, { stderr: '' }); model.add(secrets.register(r.stdout.trim()), d); } expect(fs.existsSync(canary), 'no description was ever executed').toBe(false); model.verifyDb(ws.dbPath); }); await test.step('token list stays one strictly parseable row per token at INFO and at TRACE', async () => { model.verifyList(await cli.tokenList()); model.verifyList(await cli.tokenListAll(), 'token list all', 'all'); // plain `token list` filters in SQL: one `row read` per active token only const active = await cli.run(['token', 'list'], { env: { LOG_LEVEL: 'TRACE' } }); expectCliSuccess(active); model.verifyList(parseTokenList(active.stdout), 'token list at TRACE'); expect(parseLogs(active.stderr).filter({ msg: 'row read' }), 'token list reads only the active rows').toHaveLength(model.active().length); const r = await cli.run(['token', 'list', 'all'], { env: { LOG_LEVEL: 'TRACE' } }); expectCliSuccess(r); model.verifyList(parseTokenList(r.stdout), 'token list all at TRACE', 'all'); const logs = parseLogs(r.stderr); expect(logs.unparsed, 'every TRACE line is a single well-formed record').toEqual([]); expect(logs.count({ level: 'ERROR' }), 'no forged ERROR record').toBe(0); expect(logs.has({ msg: /forged/ })).toBe(false); const read = logs.filter({ msg: 'row read' }); expect(read).toHaveLength(model.tokens.size); for (const d of forging) expect(read.some((x) => x.attrs.description === d), `description logged as one quoted attribute: ${JSON.stringify(d)}`).toBe(true); }); await test.step('TRACE server: authenticating with every token logs its description safely', async () => { const server = await startServer({ logLevel: 'TRACE' }); for (const t of model.active()) { expectContainersResponse(await http.get(server.url(), { token: t })); model.audit(t); } expect((await server.stop()).exitCode).toBe(0); const logs = server.logs(); expect(logs.unparsed).toEqual([]); expect(logs.count({ level: 'ERROR' })).toBe(0); expect(logs.has({ msg: /forged/ })).toBe(false); expect(logs.requests().every((x) => x.attrs.origin === '127.0.0.1')).toBe(true); expect(fs.existsSync(canary)).toBe(false); }); await test.step('Unicode confusables are distinct tokens/descriptions: confusable token variants never match', async () => { const target = model.active()[0]; const before = stateDigest(ws.dbPath); for (const m of nearMatches(target, rng, 400).filter((x) => x.kind === 'confusable' || x.kind === 'zero-width').slice(0, 10)) { expectCliFailure(await cli.run(['token', 'delete', m.value]), { exitCode: 1, message: 'token not found' }); } expect(stateDigest(ws.dbPath)).toBe(before); const rows = await cli.tokenList(); expect(rows.filter((r) => r.description === 'admin')).toHaveLength(1); expect(rows.filter((r) => r.description === '\u{430}dmin')).toHaveLength(1); }); await test.step('NUL: argv/env cannot carry it (platform), HTTP rejects or does not match it', async () => { const before = stateDigest(ws.dbPath); // execve(2) takes NUL-terminated strings: Node refuses to spawn, the binary never runs await expect(cli.run(['token', 'new', 'a\x00b'])).rejects.toThrow(/harness:spawn|ERR_INVALID_ARG_VALUE|null bytes/); await expect(cli.run(['token', 'list'], { env: { LOG_LEVEL: 'INFO\x00' } })).rejects.toThrow(/harness:spawn|ERR_INVALID_ARG_VALUE|null bytes/); // a shell drops NUL from command substitution: the stored description has no NUL const sh = await cli.shell(`"$DPSAPI_BIN" token new "$(printf 'a\\000b')"`); expectCliSuccess(sh); const tok = sh.stdout.trim(); expect(readToken(ws.dbPath, tok)!.descriptionHex).toBe('6162'); model.add(tok, 'ab'); expect(stateDigest(ws.dbPath)).not.toBe(before); const server = await startServer(); const t = model.active()[0]; expect(onlyResponse(await raw(http, server, req([`Authorization: Bearer ${t}\x00`])), 'nul header').status).toBe(400); expect(onlyResponse(await raw(http, server, req([`Authorization: Bearer ${t.slice(0, 20)}%00${t.slice(20)}`])), 'pct nul').status).toBe(401); expectErrorResponse(onlyResponse(await raw(http, server, req([`Authorization: Bearer ${t}`], { target: `${ENDPOINT}%00` })), 'nul path'), 404); expectContainersResponse(onlyResponse(await raw(http, server, req([`Authorization: Bearer ${t}`], { target: `${ENDPOINT}?a=%00` })), 'nul query')); model.audit(t); expect((await server.stop()).exitCode).toBe(0); }); model.verifyDb(ws.dbPath, 'final state'); }); test('forwarding headers cannot spoof the audited origin (IPv4 and IPv6 listeners, 40 spoof variants each)', async ({ cli, ws, startServer, http, rng }) => { const T = await cli.tokenNew('origin'); const spoofs = ['X-Forwarded-For', 'Forwarded', 'X-Real-IP', 'True-Client-IP', 'CF-Connecting-IP', 'X-Client-IP', 'X-Originating-IP', 'X-Remote-Addr', 'X-Remote-IP', 'Client-IP', 'X-Cluster-Client-IP', 'Fastly-Client-IP', 'X-ProxyUser-Ip', 'Via']; const values = ['6.6.6.6', '6.6.6.6, 127.0.0.1', 'for=6.6.6.6;proto=https', 'for="[2001:db8::6]:1"', 'unknown', '::1', '127.0.0.1', '10.0.0.1, 10.0.0.2, 10.0.0.3', '