Restrict raw beta file downloads to operators
This commit is contained in:
@@ -39,6 +39,7 @@ export function routePermission(routeId: string | null, method: string): RoutePe
|
||||
// bytes, and unfiltered diagnostics may contain runtime credentials.
|
||||
if (routeId === '/configs/[id]' || routeId === '/api/configs/[id]' || routeId === '/api/configs/inspect'
|
||||
|| routeId === '/api/campaigns/[id]/file/[fileId]' || routeId === '/api/deployments/[id]/file/[fileId]'
|
||||
|| routeId === '/api/betas/[id]/revisions/[revision]/files/[scriptId]'
|
||||
|| routeId === '/api/servers/[name]/logs/[file]' || routeId === '/api/servers/[name]/telemetry-requests') return 'operator';
|
||||
|
||||
return reading ? 'viewer' : 'operator';
|
||||
|
||||
@@ -61,6 +61,7 @@ describe('management route permissions', () => {
|
||||
it.each([
|
||||
'/configs/[id]', '/api/configs/[id]', '/api/configs/inspect',
|
||||
'/api/campaigns/[id]/file/[fileId]', '/api/deployments/[id]/file/[fileId]',
|
||||
'/api/betas/[id]/revisions/[revision]/files/[scriptId]',
|
||||
'/api/servers/[name]/logs/[file]', '/api/servers/[name]/telemetry-requests'
|
||||
])('prevents viewer access to secret-bearing raw content at %s', route => {
|
||||
for (const method of ['GET', 'HEAD']) {
|
||||
|
||||
@@ -125,6 +125,17 @@ describe('browser authentication guard', () => {
|
||||
if (expectedStatus === 200) { expect(call.resolve).toHaveBeenCalledOnce(); expect(call.event.locals.user).toEqual(session.user); }
|
||||
else expect(call.resolve).not.toHaveBeenCalled();
|
||||
});
|
||||
it.each(['GET', 'HEAD'])('restricts raw beta file %s requests to operators and administrators', async method => {
|
||||
for (const role of ['viewer', 'operator', 'admin'] as const) {
|
||||
signIn(role);
|
||||
const call = requestFor('/api/betas/[id]/revisions/[revision]/files/[scriptId]', {
|
||||
method, path: '/api/betas/1/revisions/1/files/1'
|
||||
});
|
||||
expect((await call.invoke()).status).toBe(role === 'viewer' ? 403 : 200);
|
||||
if (role === 'viewer') expect(call.resolve).not.toHaveBeenCalled();
|
||||
else expect(call.resolve).toHaveBeenCalledOnce();
|
||||
}
|
||||
});
|
||||
it('requires temporary-password users to change it even if their role is administrator', async () => {
|
||||
signIn('admin', true);
|
||||
await expect(requestFor('/settings').invoke()).rejects.toMatchObject({ status: 303, location: '/account' });
|
||||
|
||||
Reference in New Issue
Block a user