Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

fix: reject requests when cors origin list is empty #3674

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions packages/ipfs-http-server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,31 @@ async function serverCreator (serverAddrs, createServer, ipfs, cors) {
return servers
}

/**
* @param {string} str
* @param {string[]} allowedOrigins
*/
function isAllowedOrigin (str, allowedOrigins = []) {
if (!str) {
return false
}

const url = new URL(str)
const origin = url.protocol + '//' + url.host

for (const allowedOrigin of allowedOrigins) {
if (allowedOrigin === '*') {
return true
}

if (allowedOrigin === origin) {
return true
}
}

return false
}

class HttpApi {
/**
* @param {IPFS} ipfs
Expand Down Expand Up @@ -175,11 +200,17 @@ class HttpApi {

const headers = request.headers || {}
const origin = headers.origin || ''
const referrer = headers.referrer || ''
const referer = headers.referer || ''
const userAgent = headers['user-agent'] || ''

// If these are set, we leave up to CORS and CSRF checks.
if (origin || referrer) {
// If these are set, check them against the configured list
if (origin || referer) {
if (!isAllowedOrigin(origin || referer, cors.origin)) {
// Hapi will not allow an empty CORS origin list so we have to manually
// reject the request if CORS origins have not been configured
throw Boom.forbidden()
}

return h.continue
}

Expand Down
62 changes: 62 additions & 0 deletions packages/ipfs-http-server/test/cors.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,23 @@ describe('cors', () => {
}
}, { ipfs, cors: { origin: [origin] } })

expect(res).to.have.property('statusCode', 200)
expect(res).to.have.nested.property('headers.access-control-allow-origin', origin)
})

it('allows request when referer is supplied in request', async () => {
const origin = 'http://localhost:8080'
const res = await http({
method: 'POST',
url: '/api/v0/id',
headers: {
referer: origin + '/index.html'
}
}, { ipfs, cors: { origin: [origin] } })

expect(res).to.have.property('statusCode', 200)
})

it('does not allow credentials when omitted in config', async () => {
const origin = 'http://localhost:8080'
const res = await http({
Expand Down Expand Up @@ -149,5 +163,53 @@ describe('cors', () => {

expect(res).to.have.property('statusCode', 404)
})

it('rejects requests when cors origin list is empty and origin is sent', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a copy of this test but with origin = 'null', just to document expected behavior for that edge case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

const origin = 'http://localhost:8080'
const res = await http({
method: 'POST',
url: '/api/v0/id',
headers: {
origin
}
}, {
ipfs,
cors: { origin: [] }
})

expect(res).to.have.property('statusCode', 403)
})

it('rejects requests when cors origin list does not contain the correct origin and origin is sent', async () => {
const origin = 'http://localhost:8080'
const res = await http({
method: 'POST',
url: '/api/v0/id',
headers: {
origin
}
}, {
ipfs,
cors: { origin: ['http://example.com:8080'] }
})

expect(res).to.have.property('statusCode', 403)
})

it('rejects requests when cors origin list does not contain the correct origin and referer is sent', async () => {
const referer = 'http://localhost:8080/index.html'
const res = await http({
method: 'POST',
url: '/api/v0/id',
headers: {
referer
}
}, {
ipfs,
cors: { origin: ['http://example.com:8080'] }
})

expect(res).to.have.property('statusCode', 403)
})
})
})