fix: Server internal error details leaking in error messages returned to clients (#9937)

This commit is contained in:
Lucas Coratger
2025-11-23 13:51:42 +01:00
committed by GitHub
parent 38c9d2e359
commit 50edb5ab4b
35 changed files with 390 additions and 125 deletions

View File

@@ -147,9 +147,14 @@ const masterKeyHeaders = {
};
describe('schemas', () => {
let loggerErrorSpy;
beforeEach(async () => {
await reconfigureServer();
config = Config.get('test');
const logger = require('../lib/logger').default;
loggerErrorSpy = spyOn(logger, 'error').and.callThrough();
});
it('requires the master key to get all schemas', done => {
@@ -167,25 +172,29 @@ describe('schemas', () => {
});
it('requires the master key to get one schema', done => {
loggerErrorSpy.calls.reset();
request({
url: 'http://localhost:8378/1/schemas/SomeSchema',
json: true,
headers: restKeyHeaders,
}).then(fail, response => {
expect(response.status).toEqual(403);
expect(response.data.error).toEqual('unauthorized: master key is required');
expect(response.data.error).toEqual('Permission denied');
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining("unauthorized: master key is required"));
done();
});
});
it('asks for the master key if you use the rest key', done => {
loggerErrorSpy.calls.reset();
request({
url: 'http://localhost:8378/1/schemas',
json: true,
headers: restKeyHeaders,
}).then(fail, response => {
expect(response.status).toEqual(403);
expect(response.data.error).toEqual('unauthorized: master key is required');
expect(response.data.error).toEqual('Permission denied');
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining("unauthorized: master key is required"));
done();
});
});
@@ -1826,6 +1835,7 @@ describe('schemas', () => {
},
},
}).then(() => {
loggerErrorSpy.calls.reset();
const object = new Parse.Object('AClass');
object.set('hello', 'world');
return object.save().then(
@@ -1834,7 +1844,9 @@ describe('schemas', () => {
done();
},
err => {
expect(err.message).toEqual('Permission denied for action addField on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action addField on class AClass'));
done();
}
);
@@ -2198,13 +2210,16 @@ describe('schemas', () => {
});
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find().then(
() => {
fail('Use should hot be able to find!');
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
);
@@ -2258,13 +2273,16 @@ describe('schemas', () => {
});
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find().then(
() => {
fail('User should not be able to find!');
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
);
@@ -2343,13 +2361,16 @@ describe('schemas', () => {
});
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find().then(
() => {
fail('User should not be able to find!');
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
);
@@ -2419,13 +2440,16 @@ describe('schemas', () => {
});
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find().then(
() => {
fail('User should not be able to find!');
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
);
@@ -2450,13 +2474,16 @@ describe('schemas', () => {
);
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find().then(
() => {
fail('User should not be able to find!');
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
);
@@ -2531,6 +2558,7 @@ describe('schemas', () => {
return Parse.User.logIn('admin', 'admin');
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find();
})
@@ -2540,7 +2568,9 @@ describe('schemas', () => {
return Promise.resolve();
},
err => {
expect(err.message).toEqual('Permission denied for action create on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action create on class AClass'));
return Promise.resolve();
}
)
@@ -2548,6 +2578,7 @@ describe('schemas', () => {
return Parse.User.logIn('user2', 'user2');
})
.then(() => {
loggerErrorSpy.calls.reset();
const query = new Parse.Query('AClass');
return query.find();
})
@@ -2557,7 +2588,9 @@ describe('schemas', () => {
return Promise.resolve();
},
err => {
expect(err.message).toEqual('Permission denied for action find on class AClass.');
expect(err.message).toEqual('Permission denied');
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
expect(loggerErrorSpy).toHaveBeenCalledWith('Sanitized error:', jasmine.stringContaining('Permission denied for action find on class AClass'));
return Promise.resolve();
}
)