Skip to content

Commit 6c5d989

Browse files
authored
Merge branch 'alpha' into get-server-version
2 parents 5274574 + a742656 commit 6c5d989

15 files changed

+154
-54
lines changed

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@
2525
"space-infix-ops": "error",
2626
"no-useless-escape": "off",
2727
"require-atomic-updates": "off"
28+
},
29+
"globals": {
30+
"Parse": true
2831
}
2932
}

changelogs/CHANGELOG_alpha.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# [6.3.0-alpha.4](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.3...6.3.0-alpha.4) (2023-07-04)
2+
3+
4+
### Bug Fixes
5+
6+
* Server does not start via CLI when `auth` option is set ([#8666](https://github.com/parse-community/parse-server/issues/8666)) ([4e2000b](https://github.com/parse-community/parse-server/commit/4e2000bc563324389584ace3c090a5c1a7796a64))
7+
18
# [6.3.0-alpha.3](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.2...6.3.0-alpha.3) (2023-06-23)
29

310

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "6.3.0-alpha.3",
3+
"version": "6.3.0-alpha.4",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {
@@ -48,7 +48,7 @@
4848
"mime": "3.0.0",
4949
"mongodb": "4.10.0",
5050
"mustache": "4.2.0",
51-
"otpauth": "9.0.2",
51+
"otpauth": "9.1.2",
5252
"parse": "4.1.0",
5353
"path-to-regexp": "6.2.1",
5454
"pg-monitor": "2.0.0",

spec/CLI.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,25 @@ describe('execution', () => {
302302
done.fail(data.toString());
303303
});
304304
});
305+
306+
it('can start Parse Server with auth via CLI', done => {
307+
const env = { ...process.env };
308+
env.NODE_OPTIONS = '--dns-result-order=ipv4first';
309+
childProcess = spawn(
310+
binPath,
311+
['--databaseURI', databaseURI, './spec/configs/CLIConfigAuth.json'],
312+
{ env }
313+
);
314+
childProcess.stdout.on('data', data => {
315+
data = data.toString();
316+
console.log(data);
317+
if (data.includes('parse-server running on')) {
318+
done();
319+
}
320+
});
321+
childProcess.stderr.on('data', data => {
322+
data = data.toString();
323+
done.fail(data.toString());
324+
});
325+
});
305326
});

spec/DefinedSchemas.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ describe('DefinedSchemas', () => {
554554
});
555555
});
556556

557-
it('should not delete automatically classes', async () => {
557+
it('should not delete classes automatically', async () => {
558558
await reconfigureServer({
559559
schema: { definitions: [{ className: '_User' }, { className: 'Test' }] },
560560
});

spec/configs/CLIConfigAuth.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"appName": "test",
3+
"appId": "test",
4+
"masterKey": "test",
5+
"logLevel": "error",
6+
"auth": {
7+
"facebook": {
8+
"appIds": "test"
9+
}
10+
}
11+
}

spec/vulnerabilities.spec.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,71 @@ describe('Vulnerabilities', () => {
138138
);
139139
});
140140

141+
it('denies creating global config with polluted data', async () => {
142+
const headers = {
143+
'Content-Type': 'application/json',
144+
'X-Parse-Application-Id': 'test',
145+
'X-Parse-Master-Key': 'test',
146+
};
147+
const params = {
148+
method: 'PUT',
149+
url: 'http://localhost:8378/1/config',
150+
json: true,
151+
body: {
152+
params: {
153+
welcomeMesssage: 'Welcome to Parse',
154+
foo: { _bsontype: 'Code', code: 'shell' },
155+
},
156+
},
157+
headers,
158+
};
159+
const response = await request(params).catch(e => e);
160+
expect(response.status).toBe(400);
161+
const text = JSON.parse(response.text);
162+
expect(text.code).toBe(Parse.Error.INVALID_KEY_NAME);
163+
expect(text.error).toBe(
164+
'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.'
165+
);
166+
});
167+
168+
it('denies direct database write wih prohibited keys', async () => {
169+
const Config = require('../lib/Config');
170+
const config = Config.get(Parse.applicationId);
171+
const user = {
172+
objectId: '1234567890',
173+
username: 'hello',
174+
password: 'pass',
175+
_session_token: 'abc',
176+
foo: { _bsontype: 'Code', code: 'shell' },
177+
};
178+
await expectAsync(config.database.create('_User', user)).toBeRejectedWith(
179+
new Parse.Error(
180+
Parse.Error.INVALID_KEY_NAME,
181+
'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.'
182+
)
183+
);
184+
});
185+
186+
it('denies direct database update wih prohibited keys', async () => {
187+
const Config = require('../lib/Config');
188+
const config = Config.get(Parse.applicationId);
189+
const user = {
190+
objectId: '1234567890',
191+
username: 'hello',
192+
password: 'pass',
193+
_session_token: 'abc',
194+
foo: { _bsontype: 'Code', code: 'shell' },
195+
};
196+
await expectAsync(
197+
config.database.update('_User', { _id: user.objectId }, user)
198+
).toBeRejectedWith(
199+
new Parse.Error(
200+
Parse.Error.INVALID_KEY_NAME,
201+
'Prohibited keyword in request data: {"key":"_bsontype","value":"Code"}.'
202+
)
203+
);
204+
});
205+
141206
it('denies creating a hook with polluted data', async () => {
142207
const express = require('express');
143208
const bodyParser = require('body-parser');

src/Controllers/DatabaseController.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,11 @@ class DatabaseController {
475475
validateOnly: boolean = false,
476476
validSchemaController: SchemaController.SchemaController
477477
): Promise<any> {
478+
try {
479+
Utils.checkProhibitedKeywords(this.options, update);
480+
} catch (error) {
481+
return Promise.reject(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error));
482+
}
478483
const originalQuery = query;
479484
const originalUpdate = update;
480485
// Make a copy of the object, so we don't mutate the incoming data.
@@ -805,6 +810,11 @@ class DatabaseController {
805810
validateOnly: boolean = false,
806811
validSchemaController: SchemaController.SchemaController
807812
): Promise<any> {
813+
try {
814+
Utils.checkProhibitedKeywords(this.options, object);
815+
} catch (error) {
816+
return Promise.reject(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error));
817+
}
808818
// Make a copy of the object, so we don't mutate the incoming data.
809819
const originalObject = object;
810820
object = transformObjectACL(object);
@@ -1706,12 +1716,6 @@ class DatabaseController {
17061716
throw error;
17071717
});
17081718

1709-
await this.adapter
1710-
.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)
1711-
.catch(error => {
1712-
logger.warn('Unable to create case insensitive username index: ', error);
1713-
throw error;
1714-
});
17151719
await this.adapter
17161720
.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)
17171721
.catch(error => {

src/Options/Definitions.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ module.exports.ParseServerOptions = {
103103
env: 'PARSE_SERVER_AUTH_PROVIDERS',
104104
help:
105105
'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication',
106-
action: parsers.arrayParser,
107106
},
108107
cacheAdapter: {
109108
env: 'PARSE_SERVER_CACHE_ADAPTER',

src/Options/docs.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Options/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export interface ParseServerOptions {
149149
allowCustomObjectId: ?boolean;
150150
/* Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
151151
:ENV: PARSE_SERVER_AUTH_PROVIDERS */
152-
auth: ?(AuthAdapter[]);
152+
auth: ?{ [string]: AuthAdapter };
153153
/* Max file size for uploads, defaults to 20mb
154154
:DEFAULT: 20mb */
155155
maxUploadSize: ?string;

src/RestWrite.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ function RestWrite(config, auth, className, query, data, originalData, clientSDK
6464
}
6565
}
6666

67-
this.checkProhibitedKeywords(data);
68-
6967
// When the operation is complete, this.response may have several
7068
// fields.
7169
// response: the actual data to be returned
@@ -304,7 +302,11 @@ RestWrite.prototype.runBeforeSaveTrigger = function () {
304302
delete this.data.objectId;
305303
}
306304
}
307-
this.checkProhibitedKeywords(this.data);
305+
try {
306+
Utils.checkProhibitedKeywords(this.config, this.data);
307+
} catch (error) {
308+
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, error);
309+
}
308310
});
309311
};
310312

@@ -1798,20 +1800,5 @@ RestWrite.prototype._updateResponseWithData = function (response, data) {
17981800
return response;
17991801
};
18001802

1801-
RestWrite.prototype.checkProhibitedKeywords = function (data) {
1802-
if (this.config.requestKeywordDenylist) {
1803-
// Scan request data for denied keywords
1804-
for (const keyword of this.config.requestKeywordDenylist) {
1805-
const match = Utils.objectContainsKeyValue(data, keyword.key, keyword.value);
1806-
if (match) {
1807-
throw new Parse.Error(
1808-
Parse.Error.INVALID_KEY_NAME,
1809-
`Prohibited keyword in request data: ${JSON.stringify(keyword)}.`
1810-
);
1811-
}
1812-
}
1813-
}
1814-
};
1815-
18161803
export default RestWrite;
18171804
module.exports = RestWrite;

src/Routers/FilesRouter.js

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -175,22 +175,13 @@ export class FilesRouter {
175175
const base64 = req.body.toString('base64');
176176
const file = new Parse.File(filename, { base64 }, contentType);
177177
const { metadata = {}, tags = {} } = req.fileData || {};
178-
if (req.config && req.config.requestKeywordDenylist) {
178+
try {
179179
// Scan request data for denied keywords
180-
for (const keyword of req.config.requestKeywordDenylist) {
181-
const match =
182-
Utils.objectContainsKeyValue(metadata, keyword.key, keyword.value) ||
183-
Utils.objectContainsKeyValue(tags, keyword.key, keyword.value);
184-
if (match) {
185-
next(
186-
new Parse.Error(
187-
Parse.Error.INVALID_KEY_NAME,
188-
`Prohibited keyword in request data: ${JSON.stringify(keyword)}.`
189-
)
190-
);
191-
return;
192-
}
193-
}
180+
Utils.checkProhibitedKeywords(config, metadata);
181+
Utils.checkProhibitedKeywords(config, tags);
182+
} catch (error) {
183+
next(new Parse.Error(Parse.Error.INVALID_KEY_NAME, error));
184+
return;
194185
}
195186
file.setTags(tags);
196187
file.setMetadata(metadata);

src/Utils.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,18 @@ class Utils {
358358
}
359359
return false;
360360
}
361+
362+
static checkProhibitedKeywords(config, data) {
363+
if (config?.requestKeywordDenylist) {
364+
// Scan request data for denied keywords
365+
for (const keyword of config.requestKeywordDenylist) {
366+
const match = Utils.objectContainsKeyValue(data, keyword.key, keyword.value);
367+
if (match) {
368+
throw `Prohibited keyword in request data: ${JSON.stringify(keyword)}.`;
369+
}
370+
}
371+
}
372+
}
361373
}
362374

363375
module.exports = Utils;

0 commit comments

Comments
 (0)