fix: Deny request if master key is not set in Parse Server option masterKeyIps regardless of ACL and CLP (#8957)
BREAKING CHANGE: A request using the master key will now be rejected as unauthorized if the IP from which the request originates is not set in the Parse Server option `masterKeyIps`, even if the request does not require the master key permission, for example for a public object in a public class class.
This commit is contained in:
@@ -33,6 +33,9 @@ describe('middlewares', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should use _ContentType if provided', done => {
|
it('should use _ContentType if provided', done => {
|
||||||
|
AppCachePut(fakeReq.body._ApplicationId, {
|
||||||
|
masterKeyIps: ['127.0.0.1'],
|
||||||
|
});
|
||||||
expect(fakeReq.headers['content-type']).toEqual(undefined);
|
expect(fakeReq.headers['content-type']).toEqual(undefined);
|
||||||
const contentType = 'image/jpeg';
|
const contentType = 'image/jpeg';
|
||||||
fakeReq.body._ContentType = contentType;
|
fakeReq.body._ContentType = contentType;
|
||||||
@@ -153,25 +156,23 @@ describe('middlewares', () => {
|
|||||||
});
|
});
|
||||||
fakeReq.ip = '127.0.0.1';
|
fakeReq.ip = '127.0.0.1';
|
||||||
fakeReq.headers['x-parse-master-key'] = 'masterKey';
|
fakeReq.headers['x-parse-master-key'] = 'masterKey';
|
||||||
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
|
||||||
expect(fakeReq.auth.isMaster).toBe(false);
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
||||||
|
} catch (err) {
|
||||||
|
error = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
expect(error.message).toEqual(`unauthorized`);
|
||||||
expect(logger.error).toHaveBeenCalledWith(
|
expect(logger.error).toHaveBeenCalledWith(
|
||||||
`Request using master key rejected as the request IP address '127.0.0.1' is not set in Parse Server option 'masterKeyIps'.`
|
`Request using master key rejected as the request IP address '127.0.0.1' is not set in Parse Server option 'masterKeyIps'.`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not succeed if the ip does not belong to masterKeyIps list', async () => {
|
it('should not succeed and log if the ip does not belong to maintenanceKeyIps list', async () => {
|
||||||
AppCachePut(fakeReq.body._ApplicationId, {
|
|
||||||
masterKey: 'masterKey',
|
|
||||||
masterKeyIps: ['10.0.0.1'],
|
|
||||||
});
|
|
||||||
fakeReq.ip = '127.0.0.1';
|
|
||||||
fakeReq.headers['x-parse-master-key'] = 'masterKey';
|
|
||||||
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
|
||||||
expect(fakeReq.auth.isMaster).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not succeed if the ip does not belong to maintenanceKeyIps list', async () => {
|
|
||||||
const logger = require('../lib/logger').logger;
|
const logger = require('../lib/logger').logger;
|
||||||
spyOn(logger, 'error').and.callFake(() => {});
|
spyOn(logger, 'error').and.callFake(() => {});
|
||||||
AppCachePut(fakeReq.body._ApplicationId, {
|
AppCachePut(fakeReq.body._ApplicationId, {
|
||||||
@@ -180,8 +181,17 @@ describe('middlewares', () => {
|
|||||||
});
|
});
|
||||||
fakeReq.ip = '10.0.0.2';
|
fakeReq.ip = '10.0.0.2';
|
||||||
fakeReq.headers['x-parse-maintenance-key'] = 'masterKey';
|
fakeReq.headers['x-parse-maintenance-key'] = 'masterKey';
|
||||||
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
|
||||||
expect(fakeReq.auth.isMaintenance).toBe(false);
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await new Promise(resolve => middlewares.handleParseHeaders(fakeReq, fakeRes, resolve));
|
||||||
|
} catch (err) {
|
||||||
|
error = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
expect(error.message).toEqual(`unauthorized`);
|
||||||
expect(logger.error).toHaveBeenCalledWith(
|
expect(logger.error).toHaveBeenCalledWith(
|
||||||
`Request using maintenance key rejected as the request IP address '10.0.0.2' is not set in Parse Server option 'maintenanceKeyIps'.`
|
`Request using maintenance key rejected as the request IP address '10.0.0.2' is not set in Parse Server option 'maintenanceKeyIps'.`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -246,6 +246,10 @@ export function handleParseHeaders(req, res, next) {
|
|||||||
`Request using master key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'masterKeyIps'.`
|
`Request using master key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'masterKeyIps'.`
|
||||||
);
|
);
|
||||||
isMaster = false;
|
isMaster = false;
|
||||||
|
const error = new Error();
|
||||||
|
error.status = 403;
|
||||||
|
error.message = `unauthorized`;
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMaster) {
|
if (isMaster) {
|
||||||
|
|||||||
Reference in New Issue
Block a user