Skip to content

Commit a8b917c

Browse files
megothmichielbdejong
authored andcommitted
Redo #1122 on top of latest release branch
1 parent 0339003 commit a8b917c

File tree

5 files changed

+117
-1
lines changed

5 files changed

+117
-1
lines changed

lib/acl-checker.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class ACLChecker {
5757
const modes = [ACL(mode)]
5858
const agentOrigin = this.agentOrigin
5959
const trustedOrigins = this.trustedOrigins
60-
const accessDenied = aclCheck.accessDenied(acl.graph, resource, directory, aclFile, agent, modes, agentOrigin, trustedOrigins)
60+
const originTrustedModes = agent && agentOrigin ? await this.getOriginTrustedModes(agent, agentOrigin) : []
61+
const accessDenied = aclCheck.accessDenied(acl.graph, resource, directory, aclFile, agent, modes, agentOrigin, trustedOrigins, originTrustedModes)
6162

6263
if (accessDenied && user) {
6364
this.messagesCached[cacheKey].push(HTTPError(403, accessDenied))
@@ -68,6 +69,26 @@ class ACLChecker {
6869
return this.aclCached[cacheKey]
6970
}
7071

72+
async getOriginTrustedModes (agent, agentOrigin) {
73+
let agentStore
74+
try {
75+
this.requests[agent.uri] = this.requests[agent.uri] || this.fetch(agent.uri)
76+
agentStore = await this.requests[agent.uri]
77+
} catch (err) {
78+
if (err && (err.code === 'ENOENT' || err.status === 404)) {
79+
// If we're unable to resolve the agent, we conclude that origin has no trusted modes
80+
this.requests[agent.uri] = Promise.resolve(null)
81+
return Promise.resolve([])
82+
}
83+
debug(err)
84+
throw err
85+
}
86+
if (agentStore) {
87+
return aclCheck.getTrustedModesForOrigin(agentStore, agent, agentOrigin)
88+
}
89+
return Promise.resolve([])
90+
}
91+
7192
async getError (user, mode) {
7293
const cacheKey = `${mode}-${user}`
7394
this.aclCached[cacheKey] = this.aclCached[cacheKey] || this.can(user, mode)

test/integration/authentication-oidc-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ describe('Authentication API (OIDC)', () => {
3535
let bobDbPath = path.join(__dirname,
3636
'../resources/accounts-scenario/bob/db')
3737

38+
const trustedAppUri = 'https://trusted.app'
39+
3840
const serverConfig = {
3941
sslKey: path.join(__dirname, '../keys/key.pem'),
4042
sslCert: path.join(__dirname, '../keys/cert.pem'),
@@ -437,6 +439,48 @@ describe('Authentication API (OIDC)', () => {
437439
expect(response).to.have.property('status', 401)
438440
})
439441
})
442+
443+
describe('with trusted app and no cookie', () => {
444+
before(done => {
445+
alice.get('/private-for-alice.txt')
446+
.set('Origin', trustedAppUri)
447+
.end((err, res) => {
448+
response = res
449+
done(err)
450+
})
451+
})
452+
453+
it('should return a 401', () => expect(response).to.have.property('status', 401))
454+
})
455+
456+
describe('with trusted app and malicious cookie', () => {
457+
before(done => {
458+
var malcookie = cookie.replace(/connect\.sid=(\S+)/, 'connect.sid=l33th4x0rzp0wn4g3;')
459+
alice.get('/private-for-alice.txt')
460+
.set('Cookie', malcookie)
461+
.set('Origin', trustedAppUri)
462+
.end((err, res) => {
463+
response = res
464+
done(err)
465+
})
466+
})
467+
468+
it('should return a 401', () => expect(response).to.have.property('status', 401))
469+
})
470+
471+
describe('with trusted app and correct cookie', () => {
472+
before(done => {
473+
alice.get('/private-for-alice.txt')
474+
.set('Cookie', cookie)
475+
.set('Origin', trustedAppUri)
476+
.end((err, res) => {
477+
response = res
478+
done(err)
479+
})
480+
})
481+
482+
it('should return a 200', () => expect(response).to.have.property('status', 200))
483+
})
440484
})
441485
})
442486

test/integration/authentication-oidc-with-strict-origins-turned-off-test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ describe('Authentication API (OIDC) - With strict origins turned off', () => {
3535
const bobServerUri = `https://localhost:${bobServerPort}`
3636
let bobDbPath = path.join(__dirname, '../resources/accounts-strict-origin-off/bob/db')
3737

38+
const trustedAppUri = 'https://trusted.app'
39+
3840
const serverConfig = {
3941
sslKey: path.join(__dirname, '../keys/key.pem'),
4042
sslCert: path.join(__dirname, '../keys/cert.pem'),
@@ -194,6 +196,18 @@ describe('Authentication API (OIDC) - With strict origins turned off', () => {
194196
})
195197
})
196198

199+
it('should return a 401', () => expect(response).to.have.property('status', 401))
200+
})
201+
describe('and trusted app', () => {
202+
before(done => {
203+
alice.get('/private-for-alice.txt')
204+
.set('Origin', trustedAppUri)
205+
.end((err, res) => {
206+
response = res
207+
done(err)
208+
})
209+
})
210+
197211
it('should return a 401', () => expect(response).to.have.property('status', 401))
198212
})
199213
})
@@ -251,6 +265,21 @@ describe('Authentication API (OIDC) - With strict origins turned off', () => {
251265
// Even if origin checking is disabled, then this should return a 401 because cookies should not be trusted cross-origin
252266
it('should return a 401', () => expect(response).to.have.property('status', 401))
253267
})
268+
269+
describe('and trusted app', () => {
270+
// Trusted apps are not supported when strictOrigin check is turned off
271+
before(done => {
272+
alice.get('/private-for-alice.txt')
273+
.set('Cookie', cookie)
274+
.set('Origin', trustedAppUri)
275+
.end((err, res) => {
276+
response = res
277+
done(err)
278+
})
279+
})
280+
281+
it('should return a 401', () => expect(response).to.have.property('status', 401))
282+
})
254283
})
255284

256285
describe('with malicious cookie', () => {
@@ -310,6 +339,20 @@ describe('Authentication API (OIDC) - With strict origins turned off', () => {
310339

311340
it('should return a 401', () => expect(response).to.have.property('status', 401))
312341
})
342+
343+
describe('and trusted app', () => {
344+
before(done => {
345+
alice.get('/private-for-alice.txt')
346+
.set('Cookie', malcookie)
347+
.set('Origin', trustedAppUri)
348+
.end((err, res) => {
349+
response = res
350+
done(err)
351+
})
352+
})
353+
354+
it('should return a 401', () => expect(response).to.have.property('status', 401))
355+
})
313356
})
314357
})
315358
})
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
2+
3+
<#me> acl:trustedApp [ acl:origin <https://trusted.app>;
4+
acl:mode acl:Read, acl:Write, acl:Append, acl:Control].
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
2+
3+
<#me> acl:trustedApp [ acl:origin <https://trusted.app>;
4+
acl:mode acl:Read, acl:Write, acl:Append, acl:Control].

0 commit comments

Comments
 (0)