]> git.ardis.lu - envpass/commitdiff
Verify `Content-Type` header on POST
authorArdis Lu <ardisglu@gmail.com>
Fri, 22 May 2026 05:33:15 +0000 (22:33 -0700)
committerArdis Lu <ardisglu@gmail.com>
Fri, 22 May 2026 05:33:15 +0000 (22:33 -0700)
Setting this header to `application/json` forces the request to be CORS preflighted (i.e. not a "simple request"). This is further security hardening against cross-origin requests from a web browser.

src/getPrf.js
test/getPrf.test.js

index 3e39e36e71d369891fdb4542497a99fabbaeb703..23aeebfb101e20e132661d2031448cac9fd2e69a 100644 (file)
@@ -94,6 +94,10 @@ export async function getPrf(options = {}) {
         response.writeHead(403).end();
         return;
       }
+      if (request.headers['content-type'] !== 'application/json') {
+        response.writeHead(400).end();
+        return;
+      }
       let body = '';
       request.on('data', chunk => body += chunk);
       request.on('end', () => {
index f5935954729fb3a8a632684e0a46b7a293494443..81ea63d32df74bf973eb74ba50adb309166489c5 100644 (file)
@@ -19,14 +19,16 @@ suite('getPrf.js (server)', () => {
     const challenge = searchParams.get('challenge');
     const prf = 'deadbeef000000000000000000000000000000000000000000000000cafebabe';
 
-    deepStrictEqual((await fetch(origin, { method: 'POST', body: JSON.stringify({ challenge, prf }) })).status, 403); // No origin
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin: 'null' }, body: JSON.stringify({ challenge, prf }) })).status, 403); // Null origin
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin: 'https://example.com' }, body: JSON.stringify({ challenge, prf }) })).status, 403); // Bad origin
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ prf }) })).status, 401); // No challenge
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ challenge: 'INVALID', prf }) })).status, 401); // Bad challenge
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ challenge }) })).status, 400); // No prf
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ challenge, prf: 'INVALID' }) })).status, 400); // Bad prf
-    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ challenge, prf }) })).status, 200); // Good
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge, prf }) })).status, 403); // No origin
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin: 'null', 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge, prf }) })).status, 403); // Null origin
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin: 'https://example.com', 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge, prf }) })).status, 403); // Bad origin
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin }, body: JSON.stringify({ challenge, prf }) })).status, 400); // No Content-Type
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'INVALID' }, body: JSON.stringify({ challenge, prf }) })).status, 400); // Bad Content-Type
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'application/json' }, body: JSON.stringify({ prf }) })).status, 401); // No challenge
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge: 'INVALID', prf }) })).status, 401); // Bad challenge
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge }) })).status, 400); // No prf
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge, prf: 'INVALID' }) })).status, 400); // Bad prf
+    deepStrictEqual((await fetch(origin, { method: 'POST', headers: { origin, 'Content-Type': 'application/json' }, body: JSON.stringify({ challenge, prf }) })).status, 200); // Good
     deepStrictEqual(await prfActual, Uint8Array.fromHex(prf));
   });
   test('window expiration works', async (t) => {
This page took 0.043717 seconds and 4 git commands to generate.