From 6b7f666d94d898ffcf4c244e88ae818eaf93940e Mon Sep 17 00:00:00 2001 From: "Aaron K. Clark" Date: Tue, 19 May 2026 13:57:34 -0500 Subject: [PATCH] test(metrics): cover the equal-length wrong-token + malformed-header paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `checkMetricsAuth` in `app/middleware/metrics.js` branches three ways: 1. Missing Authorization header → 401. 2. Non-"Bearer " shape → 401. 3. Bearer-prefixed but token doesn't match: a. Equal-length supplied vs required → timingSafeEqual. b. Different-length → sha256-of-both fallback, returning false. Pre-existing tests covered (1), (3b) (the "wrong token" case used a value of different length than the configured token), and the happy path. Missing: - (2) — a header without the `Bearer ` prefix. Without an explicit test, a future "lenient parser" refactor that fell through to treat the raw header value as the token could slip past CI. - (3a) — the timingSafeEqual branch with a same-length wrong token. A future "optimization" that returned true on equal bytes for the wrong reason would be invisible until a security scanner caught it. Adds both cases; test count 788 → 790. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/api/metrics.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/api/metrics.test.js b/tests/api/metrics.test.js index b49a772..354fe51 100644 --- a/tests/api/metrics.test.js +++ b/tests/api/metrics.test.js @@ -101,4 +101,32 @@ describe('GET /metrics — METRICS_BEARER_TOKEN gate', () => { .set('Authorization', 'Bearer secret-test-token'); expect(res.status).toBe(200); }); + + test('401 on an equal-length wrong token (exercises the timingSafeEqual branch)', async () => { + // METRICS_BEARER_TOKEN = 'secret-test-token' (17 chars). + // The "wrong token" test above uses a different-length value + // and hits the length-mismatch branch in checkMetricsAuth + // (sha256-of-both fallback returning `... && false`). This + // case pins the equal-length branch: same byte count, wrong + // contents. Without an explicit case the timingSafeEqual + // path is uncovered and a future "optimization" that returns + // true on a length-equal comparison would slip through. + const sameLengthWrong = 'XXXXXX-XXXX-XXXXX'; // 17 chars, all-X + expect(sameLengthWrong.length).toBe('secret-test-token'.length); + const res = await request(app) + .get('/metrics') + .set('Authorization', `Bearer ${sameLengthWrong}`); + expect(res.status).toBe(401); + }); + + test('401 on a malformed Authorization header (no Bearer prefix)', async () => { + // RFC 6750 Bearer-token format is `Authorization: Bearer `. + // Anything without the `Bearer ` prefix should fail the regex + // match in checkMetricsAuth and return 401 — not silently + // pass through as if the header were missing. + const res = await request(app) + .get('/metrics') + .set('Authorization', 'secret-test-token'); + expect(res.status).toBe(401); + }); });