From 5a7f940bc6ed3b052980c430e78c2d705dbe9d28 Mon Sep 17 00:00:00 2001 From: "hemanth.hm" Date: Wed, 30 Mar 2022 00:11:00 -0700 Subject: [PATCH] feat: CORB check. (#1312) * feat: CORB check. * Update lib/fetch/util.js * Update test/fetch/util.js Co-authored-by: Robert Nagy --- lib/fetch/util.js | 38 +++++++++++++++++++++++++++++++++++++- test/fetch/util.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/lib/fetch/util.js b/lib/fetch/util.js index eea3905586d..7e5db0f335b 100644 --- a/lib/fetch/util.js +++ b/lib/fetch/util.js @@ -318,7 +318,43 @@ function sameOrigin (A, B) { // https://fetch.spec.whatwg.org/#corb-check function CORBCheck (request, response) { - // TODO + // 1. If request’s initiator is "download", then return allowed. + if (request.initiator === 'download') { + return 'allowed' + } + + // 2. If request’s current URL’s scheme is not an HTTP(S) scheme, then return allowed. + if (!/^https?$/.test(request.currentURL.scheme)) { + return 'allowed' + } + + // 3. Let mimeType be the result of extracting a MIME type from response’s header list. + const mimeType = response.headersList.get('content-type') + + + // 4. If mimeType is failure, then return allowed. + if (mimeType === '') { + return 'allowed' + } + + // 5. If response’s status is 206 and mimeType is a CORB-protected MIME type, then return blocked. + + const isCORBProtectedMIME = + (/^text\/html\b/.test(mimeType) || + /^application\/javascript\b/.test(mimeType) || + /^application\/xml\b/.test(mimeType)) && !/^application\/xml\+svg\b/.test(mimeType) + + if (response.status === 206 && isCORBProtectedMIME) { + return 'blocked' + } + + // 6. If determine nosniff with response’s header list is true and mimeType is a CORB-protected MIME type or its essence is "text/plain", then return blocked. + // https://fetch.spec.whatwg.org/#determinenosniff + if (response.headersList.get('x-content-type-options') && isCORBProtectedMIME) { + return 'blocked' + } + + // 7. Return allowed. return 'allowed' } diff --git a/test/fetch/util.js b/test/fetch/util.js index f1f55b4c2c2..bd77ecdec84 100644 --- a/test/fetch/util.js +++ b/test/fetch/util.js @@ -113,3 +113,48 @@ test('sameOrigin', (t) => { t.end() }) + +test('CORBCheck', (t) => { + const allowedRequests = [{ + initiator: 'download', + currentURL: { scheme: '' } + }, { + initiator: '', + currentURL: { scheme: 'https' } + } + ] + + const response = { headersList: { get () { return '' } } } + + allowedRequests.forEach((request) => { + t.ok(util.CORBCheck(request, response)) + }) + + t.ok(util.CORBCheck({ + initiator: '', + currentURL: { scheme: '' } + }, response)) + + const protectedResponses = [{ + status: 206, + headersList: { get () { return 'text/html' } } + }, { + status: 206, + headersList: { get () { return 'application/javascript' } } + }, { + status: 206, + headersList: { get () { return 'application/xml' } } + }, { + status: 218, + headersList: { get (type) { return type === 'content-type' ? 'text/html' : 'x-content-type-options' } } + }] + + protectedResponses.forEach(response => { + t.equal(util.CORBCheck({ + initiator: '', + currentURL: { scheme: 'https' } + }, response), 'blocked') + }) + + t.end() +})