fix: improve security by deprecating creating users with public access by default (#7319)
This commit is contained in:
@@ -75,6 +75,7 @@ export class Config {
|
||||
fileUpload,
|
||||
pages,
|
||||
security,
|
||||
enforcePrivateUsers,
|
||||
}) {
|
||||
if (masterKey === readOnlyMasterKey) {
|
||||
throw new Error('masterKey and readOnlyMasterKey should be different');
|
||||
@@ -111,6 +112,13 @@ export class Config {
|
||||
this.validateIdempotencyOptions(idempotencyOptions);
|
||||
this.validatePagesOptions(pages);
|
||||
this.validateSecurityOptions(security);
|
||||
this.validateEnforcePrivateUsers(enforcePrivateUsers);
|
||||
}
|
||||
|
||||
static validateEnforcePrivateUsers(enforcePrivateUsers) {
|
||||
if (typeof enforcePrivateUsers !== 'boolean') {
|
||||
throw 'Parse Server option enforcePrivateUsers must be a boolean.';
|
||||
}
|
||||
}
|
||||
|
||||
static validateSecurityOptions(security) {
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
* The deprecations.
|
||||
*
|
||||
* Add deprecations to the array using the following keys:
|
||||
* - `optionKey`: The option key incl. its path, e.g. `security.enableCheck`.
|
||||
* - `envKey`: The environment key, e.g. `PARSE_SERVER_SECURITY`.
|
||||
* - `changeNewKey`: Set the new key name if the current key will be replaced,
|
||||
* - `optionKey` {String}: The option key incl. its path, e.g. `security.enableCheck`.
|
||||
* - `envKey` {String}: The environment key, e.g. `PARSE_SERVER_SECURITY`.
|
||||
* - `changeNewKey` {String}: Set the new key name if the current key will be replaced,
|
||||
* or set to an empty string if the current key will be removed without replacement.
|
||||
* - `changeNewDefault`: Set the new default value if the key's default value
|
||||
* - `changeNewDefault` {String}: Set the new default value if the key's default value
|
||||
* will change in a future version.
|
||||
* - `solution`: The instruction to resolve this deprecation warning. Optional. This
|
||||
* instruction must not include the deprecation warning which is auto-generated.
|
||||
@@ -22,4 +22,5 @@ module.exports = [
|
||||
solution:
|
||||
"Additionally, the environment variable 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS' will be deprecated and renamed to 'PARSE_SERVER_DIRECT_ACCESS' in a future version; it is currently possible to use either one.",
|
||||
},
|
||||
{ optionKey: 'enforcePrivateUsers', changeNewDefault: 'true' },
|
||||
];
|
||||
|
||||
@@ -154,6 +154,12 @@ module.exports.ParseServerOptions = {
|
||||
env: 'PARSE_SERVER_ENCRYPTION_KEY',
|
||||
help: 'Key for encrypting your files',
|
||||
},
|
||||
enforcePrivateUsers: {
|
||||
env: 'PARSE_SERVER_ENFORCE_PRIVATE_USERS',
|
||||
help: 'Set to true if new users should be created without public read and write access.',
|
||||
action: parsers.booleanParser,
|
||||
default: false,
|
||||
},
|
||||
expireInactiveSessions: {
|
||||
env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS',
|
||||
help:
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
* @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true
|
||||
* @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors
|
||||
* @property {String} encryptionKey Key for encrypting your files
|
||||
* @property {Boolean} enforcePrivateUsers Set to true if new users should be created without public read and write access.
|
||||
* @property {Boolean} expireInactiveSessions Sets whether we should expire the inactive sessions, defaults to true. If false, all new sessions are created with no expiration date.
|
||||
* @property {String} fileKey Key for your files
|
||||
* @property {Adapter<FilesAdapter>} filesAdapter Adapter module for the files sub-system
|
||||
|
||||
@@ -246,6 +246,9 @@ export interface ParseServerOptions {
|
||||
/* The security options to identify and report weak security settings.
|
||||
:DEFAULT: {} */
|
||||
security: ?SecurityOptions;
|
||||
/* Set to true if new users should be created without public read and write access.
|
||||
:DEFAULT: false */
|
||||
enforcePrivateUsers: ?boolean;
|
||||
}
|
||||
|
||||
export interface SecurityOptions {
|
||||
|
||||
@@ -1408,7 +1408,9 @@ RestWrite.prototype.runDatabaseOperation = function () {
|
||||
// default public r/w ACL
|
||||
if (!ACL) {
|
||||
ACL = {};
|
||||
ACL['*'] = { read: true, write: false };
|
||||
if (!this.config.enforcePrivateUsers) {
|
||||
ACL['*'] = { read: true, write: false };
|
||||
}
|
||||
}
|
||||
// make sure the user is not locked down
|
||||
ACL[this.data.objectId] = { read: true, write: true };
|
||||
|
||||
@@ -8,9 +8,9 @@ import Config from '../../Config';
|
||||
import Parse from 'parse/node';
|
||||
|
||||
/**
|
||||
* The security checks group for Parse Server configuration.
|
||||
* Checks common Parse Server parameters such as access keys.
|
||||
*/
|
||||
* The security checks group for Parse Server configuration.
|
||||
* Checks common Parse Server parameters such as access keys.
|
||||
*/
|
||||
class CheckGroupServerConfig extends CheckGroup {
|
||||
setName() {
|
||||
return 'Parse Server Configuration';
|
||||
@@ -21,7 +21,8 @@ class CheckGroupServerConfig extends CheckGroup {
|
||||
new Check({
|
||||
title: 'Secure master key',
|
||||
warning: 'The Parse Server master key is insecure and vulnerable to brute force attacks.',
|
||||
solution: 'Choose a longer and/or more complex master key with a combination of upper- and lowercase characters, numbers and special characters.',
|
||||
solution:
|
||||
'Choose a longer and/or more complex master key with a combination of upper- and lowercase characters, numbers and special characters.',
|
||||
check: () => {
|
||||
const masterKey = config.masterKey;
|
||||
const hasUpperCase = /[A-Z]/.test(masterKey);
|
||||
@@ -40,8 +41,9 @@ class CheckGroupServerConfig extends CheckGroup {
|
||||
}),
|
||||
new Check({
|
||||
title: 'Security log disabled',
|
||||
warning: 'Security checks in logs may expose vulnerabilities to anyone access to logs.',
|
||||
solution: 'Change Parse Server configuration to \'security.enableCheckLog: false\'.',
|
||||
warning:
|
||||
'Security checks in logs may expose vulnerabilities to anyone with access to logs.',
|
||||
solution: "Change Parse Server configuration to 'security.enableCheckLog: false'.",
|
||||
check: () => {
|
||||
if (config.security && config.security.enableCheckLog) {
|
||||
throw 1;
|
||||
@@ -50,14 +52,26 @@ class CheckGroupServerConfig extends CheckGroup {
|
||||
}),
|
||||
new Check({
|
||||
title: 'Client class creation disabled',
|
||||
warning: 'Attackers are allowed to create new classes without restriction and flood the database.',
|
||||
solution: 'Change Parse Server configuration to \'allowClientClassCreation: false\'.',
|
||||
warning:
|
||||
'Attackers are allowed to create new classes without restriction and flood the database.',
|
||||
solution: "Change Parse Server configuration to 'allowClientClassCreation: false'.",
|
||||
check: () => {
|
||||
if (config.allowClientClassCreation || config.allowClientClassCreation == null) {
|
||||
throw 1;
|
||||
}
|
||||
},
|
||||
}),
|
||||
new Check({
|
||||
title: 'Users are created without public access',
|
||||
warning:
|
||||
'Users with public read access are exposed to anyone who knows their object IDs, or to anyone who can query the Parse.User class.',
|
||||
solution: "Change Parse Server configuration to 'enforcePrivateUsers: true'.",
|
||||
check: () => {
|
||||
if (!config.enforcePrivateUsers) {
|
||||
throw 1;
|
||||
}
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user