Skip to content

Commit

Permalink
fix: validate authorization schema (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
dancastillo authored Dec 27, 2023
1 parent 358da60 commit 25edf58
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 20 deletions.
16 changes: 12 additions & 4 deletions lib/verifyBearerAuthFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ module.exports = function verifyBearerAuthFactory (options) {
}

return function verifyBearerAuth (request, reply, done) {
const header = request.raw.headers.authorization
if (!header) {
const noHeaderError = Error('missing authorization header')
function authorizationHeaderErrorFn (errorMessage) {
const noHeaderError = Error(errorMessage)
if (verifyErrorLogLevel) request.log[verifyErrorLogLevel]('unauthorized: %s', noHeaderError.message)
if (contentType) reply.header('content-type', contentType)
reply.code(401)
Expand All @@ -36,7 +35,16 @@ module.exports = function verifyBearerAuthFactory (options) {
return
}
reply.send(errorResponse(noHeaderError))
return
}

const header = request.raw.headers.authorization
if (!header) {
return authorizationHeaderErrorFn('missing authorization header')
}

const type = header.substring(0, bearerType.length)
if (type !== bearerType) {
return authorizationHeaderErrorFn('invalid authorization header')
}

const key = header.substring(bearerType.length).trim()
Expand Down
99 changes: 83 additions & 16 deletions test/verifyBearerAuthFactory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,73 @@ test('hook rejects for missing header with custom content type', (t) => {
hook(request, response)
})

test('hook rejects for wrong bearer type but same string length as `bearer`', (t) => {
t.plan(2)

const request = {
log: { error: noop },
raw: { headers: { authorization: `reraeB ${key}` } }
}
const response = {
code: () => response,
send
}

function send (body) {
t.ok(body.error)
t.match(body.error, /invalid authorization header/)
}

const hook = verifyBearerAuthFactory()
hook(request, response)
})

test('hook rejects for wrong bearer type', (t) => {
t.plan(2)

const request = {
log: { error: noop },
raw: { headers: { authorization: `fake-bearer ${key}` } }
}
const response = {
code: () => response,
send
}

function send (body) {
t.ok(body.error)
t.match(body.error, /invalid authorization header/)
}

const hook = verifyBearerAuthFactory()
hook(request, response)
})

test('hook rejects for wrong alternate Bearer', (t) => {
t.plan(2)

const bearerAlt = 'BearerAlt'
const keysAlt = { keys: new Set([key]), bearerType: bearerAlt }
const request = {
log: { error: noop },
raw: {
headers: { authorization: `tlAreraeB ${key}` }
}
}
const response = {
code: () => response,
send
}

function send (body) {
t.ok(body.error)
t.match(body.error, /invalid authorization header/)
}

const hook = verifyBearerAuthFactory(keysAlt)
hook(request, response)
})

test('hook rejects header without bearer prefix', (t) => {
t.plan(2)

Expand Down Expand Up @@ -107,7 +174,7 @@ test('hook accepts correct header', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: `bearer ${key}` }
headers: { authorization: `Bearer ${key}` }
}
}
const response = {
Expand Down Expand Up @@ -157,7 +224,7 @@ test('hook accepts correct header with extra padding', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: `bearer ${key} ` }
headers: { authorization: `Bearer ${key} ` }
}
}
const response = {
Expand All @@ -184,7 +251,7 @@ test('hook accepts correct header with auth function (promise)', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: `bearer ${key}` }
headers: { authorization: `Bearer ${key}` }
}
}
const response = {
Expand All @@ -211,7 +278,7 @@ test('hook accepts correct header with auth function (non-promise)', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: `bearer ${key}` }
headers: { authorization: `Bearer ${key}` }
}
}
const response = {
Expand All @@ -235,7 +302,7 @@ test('hook rejects wrong token with keys', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdedfg' }
headers: { authorization: 'Bearer abcdedfg' }
}
}
const response = {
Expand All @@ -261,7 +328,7 @@ test('hook rejects wrong token with custom content type', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -290,7 +357,7 @@ test('hook rejects wrong token with auth function', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}

Expand Down Expand Up @@ -330,7 +397,7 @@ test('hook rejects wrong token with function (resolved promise)', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -363,7 +430,7 @@ test('hook rejects with 500 when functions fails', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -396,7 +463,7 @@ test('hook rejects with 500 when promise rejects', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -429,7 +496,7 @@ test('hook rejects with 500 when promise rejects with non Error', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -457,7 +524,7 @@ test('hook returns proper error for valid key but failing callback', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: `bearer ${key}` }
headers: { authorization: `Bearer ${key}` }
}
}
const response = {
Expand Down Expand Up @@ -493,7 +560,7 @@ test('hook rejects with 500 when functions returns non-boolean', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -526,7 +593,7 @@ test('hook rejects with 500 when promise resolves to non-boolean', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -559,7 +626,7 @@ test('hook rejects with 500 when functions returns non-boolean (addHook: false)'
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down Expand Up @@ -587,7 +654,7 @@ test('hook rejects with 500 when promise rejects (addHook: false)', (t) => {
const request = {
log: { error: noop },
raw: {
headers: { authorization: 'bearer abcdefg' }
headers: { authorization: 'Bearer abcdefg' }
}
}
const response = {
Expand Down

0 comments on commit 25edf58

Please sign in to comment.