Skip to content

Commit bcb134c

Browse files
CryptoJonesAaron K. Clarkclaude
authored
test(metrics): cover the equal-length wrong-token + malformed-header paths (#343)
`checkMetricsAuth` in `app/middleware/metrics.js` branches three ways: 1. Missing Authorization header → 401. 2. Non-"Bearer <token>" 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: Aaron K. Clark <akclark@thenetwerk.net> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f84fd45 commit bcb134c

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

tests/api/metrics.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,32 @@ describe('GET /metrics — METRICS_BEARER_TOKEN gate', () => {
101101
.set('Authorization', 'Bearer secret-test-token');
102102
expect(res.status).toBe(200);
103103
});
104+
105+
test('401 on an equal-length wrong token (exercises the timingSafeEqual branch)', async () => {
106+
// METRICS_BEARER_TOKEN = 'secret-test-token' (17 chars).
107+
// The "wrong token" test above uses a different-length value
108+
// and hits the length-mismatch branch in checkMetricsAuth
109+
// (sha256-of-both fallback returning `... && false`). This
110+
// case pins the equal-length branch: same byte count, wrong
111+
// contents. Without an explicit case the timingSafeEqual
112+
// path is uncovered and a future "optimization" that returns
113+
// true on a length-equal comparison would slip through.
114+
const sameLengthWrong = 'XXXXXX-XXXX-XXXXX'; // 17 chars, all-X
115+
expect(sameLengthWrong.length).toBe('secret-test-token'.length);
116+
const res = await request(app)
117+
.get('/metrics')
118+
.set('Authorization', `Bearer ${sameLengthWrong}`);
119+
expect(res.status).toBe(401);
120+
});
121+
122+
test('401 on a malformed Authorization header (no Bearer prefix)', async () => {
123+
// RFC 6750 Bearer-token format is `Authorization: Bearer <token>`.
124+
// Anything without the `Bearer ` prefix should fail the regex
125+
// match in checkMetricsAuth and return 401 — not silently
126+
// pass through as if the header were missing.
127+
const res = await request(app)
128+
.get('/metrics')
129+
.set('Authorization', 'secret-test-token');
130+
expect(res.status).toBe(401);
131+
});
104132
});

0 commit comments

Comments
 (0)