Skip to content

Commit 5e85bc1

Browse files
authored
Merge ac6e2b0 into d144819
2 parents d144819 + ac6e2b0 commit 5e85bc1

File tree

9 files changed

+74
-55
lines changed

9 files changed

+74
-55
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Once you have babel running in watch mode, you can start making changes to parse
114114
* Take testing seriously! Aim to increase the test coverage with every pull request. To obtain the test coverage of the project, run: `npm run coverage`
115115
* Run the tests for the file you are working on with the following command: `npm test spec/MyFile.spec.js`
116116
* Run the tests for the whole project to make sure the code passes all tests. This can be done by running the test command for a single file but removing the test file argument. The results can be seen at *<PROJECT_ROOT>/coverage/lcov-report/index.html*.
117+
* Format your code by running `npm run clean`.
117118
* Lint your code by running `npm run lint` to make sure the code is not going to be rejected by the CI.
118119
* **Do not** publish the *lib* folder.
119120
* Mocks belong in the `spec/support` folder.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
},
102102
"scripts": {
103103
"ci:check": "node ./resources/ci/ciCheck.js",
104+
"clean": "npm run prettier && npm run lint-fix",
104105
"definitions": "node ./resources/buildConfigDefinitions.js && prettier --write 'src/Options/*.js'",
105106
"docs": "jsdoc -c ./jsdoc-conf.json",
106107
"lint": "flow && eslint --cache ./",

spec/SecurityCheck.spec.js

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@ describe('Security Check', () => {
2323
await reconfigureServer(config);
2424
}
2525

26-
const securityRequest = (options) => request(Object.assign({
27-
url: securityUrl,
28-
headers: {
29-
'X-Parse-Master-Key': Parse.masterKey,
30-
'X-Parse-Application-Id': Parse.applicationId,
31-
},
32-
followRedirects: false,
33-
}, options)).catch(e => e);
26+
const securityRequest = options =>
27+
request(
28+
Object.assign(
29+
{
30+
url: securityUrl,
31+
headers: {
32+
'X-Parse-Master-Key': Parse.masterKey,
33+
'X-Parse-Application-Id': Parse.applicationId,
34+
},
35+
followRedirects: false,
36+
},
37+
options
38+
)
39+
).catch(e => e);
3440

3541
beforeEach(async () => {
3642
groupName = 'Example Group Name';
@@ -41,7 +47,7 @@ describe('Security Check', () => {
4147
solution: 'TestSolution',
4248
check: () => {
4349
return true;
44-
}
50+
},
4551
});
4652
checkFail = new Check({
4753
group: 'TestGroup',
@@ -50,14 +56,14 @@ describe('Security Check', () => {
5056
solution: 'TestSolution',
5157
check: () => {
5258
throw 'Fail';
53-
}
59+
},
5460
});
5561
Group = class Group extends CheckGroup {
5662
setName() {
5763
return groupName;
5864
}
5965
setChecks() {
60-
return [ checkSuccess, checkFail ];
66+
return [checkSuccess, checkFail];
6167
}
6268
};
6369
config = {
@@ -154,7 +160,7 @@ describe('Security Check', () => {
154160
title: 'string',
155161
warning: 'string',
156162
solution: 'string',
157-
check: () => {}
163+
check: () => {},
158164
},
159165
{
160166
group: 'string',
@@ -203,7 +209,9 @@ describe('Security Check', () => {
203209
title: 'string',
204210
warning: 'string',
205211
solution: 'string',
206-
check: () => { throw 'error' },
212+
check: () => {
213+
throw 'error';
214+
},
207215
});
208216
expect(check._checkState == CheckState.none);
209217
check.run();
@@ -277,7 +285,7 @@ describe('Security Check', () => {
277285
});
278286

279287
it('runs all checks of all groups', async () => {
280-
const checkGroups = [ Group, Group ];
288+
const checkGroups = [Group, Group];
281289
const runner = new CheckRunner({ checkGroups });
282290
const report = await runner.run();
283291
expect(report.report.groups[0].checks[0].state).toBe(CheckState.success);
@@ -287,27 +295,27 @@ describe('Security Check', () => {
287295
});
288296

289297
it('reports correct default syntax version 1.0.0', async () => {
290-
const checkGroups = [ Group ];
298+
const checkGroups = [Group];
291299
const runner = new CheckRunner({ checkGroups, enableCheckLog: true });
292300
const report = await runner.run();
293301
expect(report).toEqual({
294302
report: {
295-
version: "1.0.0",
296-
state: "fail",
303+
version: '1.0.0',
304+
state: 'fail',
297305
groups: [
298306
{
299-
name: "Example Group Name",
300-
state: "fail",
307+
name: 'Example Group Name',
308+
state: 'fail',
301309
checks: [
302310
{
303-
title: "TestTitleSuccess",
304-
state: "success",
311+
title: 'TestTitleSuccess',
312+
state: 'success',
305313
},
306314
{
307-
title: "TestTitleFail",
308-
state: "fail",
309-
warning: "TestWarning",
310-
solution: "TestSolution",
315+
title: 'TestTitleFail',
316+
state: 'fail',
317+
warning: 'TestWarning',
318+
solution: 'TestSolution',
311319
},
312320
],
313321
},
@@ -319,7 +327,7 @@ describe('Security Check', () => {
319327
it('logs report', async () => {
320328
const logger = require('../lib/logger').logger;
321329
const logSpy = spyOn(logger, 'warn').and.callThrough();
322-
const checkGroups = [ Group ];
330+
const checkGroups = [Group];
323331
const runner = new CheckRunner({ checkGroups, enableCheckLog: true });
324332
const report = await runner.run();
325333
const titles = report.report.groups.flatMap(group => group.checks.map(check => check.title));

src/Routers/SecurityRouter.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import CheckRunner from '../Security/CheckRunner';
44

55
export class SecurityRouter extends PromiseRouter {
66
mountRoutes() {
7-
this.route('GET', '/security',
7+
this.route(
8+
'GET',
9+
'/security',
810
middleware.promiseEnforceMasterKeyAccess,
911
this._enforceSecurityCheckEnabled,
10-
async (req) => {
12+
async req => {
1113
const report = await new CheckRunner(req.config.security).run();
1214
return {
1315
status: 200,

src/Security/Check.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ class Check {
7373
* The check state.
7474
*/
7575
const CheckState = Object.freeze({
76-
none: "none",
77-
fail: "fail",
78-
success: "success",
76+
none: 'none',
77+
fail: 'fail',
78+
success: 'success',
7979
});
8080

8181
export default Check;

src/Security/CheckGroups/CheckGroupDatabase.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import Config from '../../Config';
88
import Parse from 'parse/node';
99

1010
/**
11-
* The security checks group for Parse Server configuration.
12-
* Checks common Parse Server parameters such as access keys.
13-
*/
11+
* The security checks group for Parse Server configuration.
12+
* Checks common Parse Server parameters such as access keys.
13+
*/
1414
class CheckGroupDatabase extends CheckGroup {
1515
setName() {
1616
return 'Database';
@@ -23,7 +23,8 @@ class CheckGroupDatabase extends CheckGroup {
2323
new Check({
2424
title: 'Secure database password',
2525
warning: 'The database password is insecure and vulnerable to brute force attacks.',
26-
solution: 'Choose a longer and/or more complex password with a combination of upper- and lowercase characters, numbers and special characters.',
26+
solution:
27+
'Choose a longer and/or more complex password with a combination of upper- and lowercase characters, numbers and special characters.',
2728
check: () => {
2829
const password = databaseUrl.match(/\/\/\S+:(\S+)@/)[1];
2930
const hasUpperCase = /[A-Z]/.test(password);

src/Security/CheckGroups/CheckGroupServerConfig.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import Config from '../../Config';
88
import Parse from 'parse/node';
99

1010
/**
11-
* The security checks group for Parse Server configuration.
12-
* Checks common Parse Server parameters such as access keys.
13-
*/
11+
* The security checks group for Parse Server configuration.
12+
* Checks common Parse Server parameters such as access keys.
13+
*/
1414
class CheckGroupServerConfig extends CheckGroup {
1515
setName() {
1616
return 'Parse Server Configuration';
@@ -21,7 +21,8 @@ class CheckGroupServerConfig extends CheckGroup {
2121
new Check({
2222
title: 'Secure master key',
2323
warning: 'The Parse Server master key is insecure and vulnerable to brute force attacks.',
24-
solution: 'Choose a longer and/or more complex master key with a combination of upper- and lowercase characters, numbers and special characters.',
24+
solution:
25+
'Choose a longer and/or more complex master key with a combination of upper- and lowercase characters, numbers and special characters.',
2526
check: () => {
2627
const masterKey = config.masterKey;
2728
const hasUpperCase = /[A-Z]/.test(masterKey);
@@ -41,7 +42,7 @@ class CheckGroupServerConfig extends CheckGroup {
4142
new Check({
4243
title: 'Security log disabled',
4344
warning: 'Security checks in logs may expose vulnerabilities to anyone access to logs.',
44-
solution: 'Change Parse Server configuration to \'security.enableCheckLog: false\'.',
45+
solution: "Change Parse Server configuration to 'security.enableCheckLog: false'.",
4546
check: () => {
4647
if (config.security && config.security.enableCheckLog) {
4748
throw 1;
@@ -50,8 +51,9 @@ class CheckGroupServerConfig extends CheckGroup {
5051
}),
5152
new Check({
5253
title: 'Client class creation disabled',
53-
warning: 'Attackers are allowed to create new classes without restriction and flood the database.',
54-
solution: 'Change Parse Server configuration to \'allowClientClassCreation: false\'.',
54+
warning:
55+
'Attackers are allowed to create new classes without restriction and flood the database.',
56+
solution: "Change Parse Server configuration to 'allowClientClassCreation: false'.",
5557
check: () => {
5658
if (config.allowClientClassCreation || config.allowClientClassCreation == null) {
5759
throw 1;

src/Security/CheckRunner.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class CheckRunner {
4646

4747
// If report should be written to logs
4848
if (this.enableCheckLog) {
49-
this._logReport(report)
49+
this._logReport(report);
5050
}
5151
return report;
5252
}
@@ -85,8 +85,8 @@ class CheckRunner {
8585
report: {
8686
version,
8787
state: CheckState.success,
88-
groups: []
89-
}
88+
groups: [],
89+
},
9090
};
9191

9292
// Identify report version
@@ -95,13 +95,12 @@ class CheckRunner {
9595
default:
9696
// For each check group
9797
for (const group of groups) {
98-
9998
// Create group report
10099
const groupReport = {
101100
name: group.name(),
102101
state: CheckState.success,
103102
checks: [],
104-
}
103+
};
105104

106105
// Create check reports
107106
groupReport.checks = group.checks().map(check => {
@@ -129,9 +128,9 @@ class CheckRunner {
129128
* @param {Object} report The report to log.
130129
*/
131130
_logReport(report) {
132-
133131
// Determine log level depending on whether any check failed
134-
const log = report.report.state == CheckState.success ? (s) => logger.info(s) : (s) => logger.warn(s);
132+
const log =
133+
report.report.state == CheckState.success ? s => logger.info(s) : s => logger.warn(s);
135134

136135
// Declare output
137136
const indent = ' ';
@@ -142,7 +141,7 @@ class CheckRunner {
142141

143142
// Traverse all groups and checks for compose output
144143
for (const group of report.report.groups) {
145-
output += `\n- ${group.name}`
144+
output += `\n- ${group.name}`;
146145

147146
for (const check of group.checks) {
148147
checksCount++;
@@ -166,7 +165,9 @@ class CheckRunner {
166165
`\n# #` +
167166
`\n###################################` +
168167
`\n` +
169-
`\n${failedChecksCount > 0 ? 'Warning: ' : ''}${failedChecksCount} weak security setting(s) found${failedChecksCount > 0 ? '!' : ''}` +
168+
`\n${
169+
failedChecksCount > 0 ? 'Warning: ' : ''
170+
}${failedChecksCount} weak security setting(s) found${failedChecksCount > 0 ? '!' : ''}` +
170171
`\n${checksCount} check(s) executed` +
171172
`\n${skippedCheckCount} check(s) skipped` +
172173
`\n` +
@@ -183,9 +184,12 @@ class CheckRunner {
183184
*/
184185
_getLogIconForState(state) {
185186
switch (state) {
186-
case CheckState.success: return '✅';
187-
case CheckState.fail: return '❌';
188-
default: return 'ℹ️';
187+
case CheckState.success:
188+
return '✅';
189+
case CheckState.fail:
190+
return '❌';
191+
default:
192+
return 'ℹ️';
189193
}
190194
}
191195

src/Utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class Utils {
178178
const type = types[key];
179179
const isOptional = !!type.o;
180180
const param = params[key];
181-
if (!(isOptional && param == null) && (!type.v(param))) {
181+
if (!(isOptional && param == null) && !type.v(param)) {
182182
throw `Invalid parameter ${key} must be of type ${type.t} but is ${typeof param}`;
183183
}
184184
}

0 commit comments

Comments
 (0)