Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ $ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongo

After starting the server, you can visit http://localhost:1337/playground in your browser to start playing with your GraphQL API.

**_Note:_** Do **_NOT_** use --mountPlayground option in production. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and it is the recommended option for production apps.
**_Note:_** Do **_NOT_** use --mountPlayground option in production. The GraphQL Playground exposes the master key in the browser page. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and is the recommended option for production apps.

### Using Docker

Expand All @@ -845,7 +845,7 @@ $ docker run --name my-parse-server --link my-mongo:mongo -v config-vol:/parse-s

After starting the server, you can visit http://localhost:1337/playground in your browser to start playing with your GraphQL API.

**_Note:_** Do **_NOT_** use --mountPlayground option in production. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and it is the recommended option for production apps.
**_Note:_** Do **_NOT_** use --mountPlayground option in production. The GraphQL Playground exposes the master key in the browser page. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and is the recommended option for production apps.

### Using Express.js

Expand Down Expand Up @@ -899,7 +899,7 @@ $ node index.js

After starting the app, you can visit http://localhost:1337/playground in your browser to start playing with your GraphQL API.

**_Note:_** Do **_NOT_** mount the GraphQL Playground in production. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and it is the recommended option for production apps.
**_Note:_** Do **_NOT_** mount the GraphQL Playground in production. The GraphQL Playground exposes the master key in the browser page. [Parse Dashboard](https://github.com/parse-community/parse-dashboard) has a built-in GraphQL Playground and is the recommended option for production apps.

## Checking the API health

Expand Down
8 changes: 6 additions & 2 deletions spec/SecurityCheckGroups.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Security Check Groups', () => {
config.allowClientClassCreation = false;
config.enableInsecureAuthAdapters = false;
config.graphQLPublicIntrospection = false;
config.mountPlayground = false;
await reconfigureServer(config);

const group = new CheckGroupServerConfig();
Expand All @@ -43,6 +44,7 @@ describe('Security Check Groups', () => {
expect(group.checks()[2].checkState()).toBe(CheckState.success);
expect(group.checks()[4].checkState()).toBe(CheckState.success);
expect(group.checks()[5].checkState()).toBe(CheckState.success);
expect(group.checks()[6].checkState()).toBe(CheckState.success);
});

it('checks fail correctly', async () => {
Expand All @@ -51,6 +53,7 @@ describe('Security Check Groups', () => {
config.allowClientClassCreation = true;
config.enableInsecureAuthAdapters = true;
config.graphQLPublicIntrospection = true;
config.mountPlayground = true;
await reconfigureServer(config);

const group = new CheckGroupServerConfig();
Expand All @@ -60,6 +63,7 @@ describe('Security Check Groups', () => {
expect(group.checks()[2].checkState()).toBe(CheckState.fail);
expect(group.checks()[4].checkState()).toBe(CheckState.fail);
expect(group.checks()[5].checkState()).toBe(CheckState.fail);
expect(group.checks()[6].checkState()).toBe(CheckState.fail);
});

it_only_db('mongo')('checks succeed correctly (MongoDB specific)', async () => {
Expand All @@ -69,7 +73,7 @@ describe('Security Check Groups', () => {

const group = new CheckGroupServerConfig();
await group.run();
expect(group.checks()[6].checkState()).toBe(CheckState.success);
expect(group.checks()[7].checkState()).toBe(CheckState.success);
});

it_only_db('mongo')('checks fail correctly (MongoDB specific)', async () => {
Expand All @@ -79,7 +83,7 @@ describe('Security Check Groups', () => {

const group = new CheckGroupServerConfig();
await group.run();
expect(group.checks()[6].checkState()).toBe(CheckState.fail);
expect(group.checks()[7].checkState()).toBe(CheckState.fail);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/Options/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ module.exports.ParseServerOptions = {
},
mountPlayground: {
env: 'PARSE_SERVER_MOUNT_PLAYGROUND',
help: 'Mounts the GraphQL Playground - never use this option in production',
help: 'Mounts the GraphQL Playground which exposes the master key in the browser - never use this option in production',
action: parsers.booleanParser,
default: false,
},
Expand Down
2 changes: 1 addition & 1 deletion src/Options/docs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ export interface ParseServerOptions {
:ENV: PARSE_SERVER_GRAPHQL_PUBLIC_INTROSPECTION
:DEFAULT: false */
graphQLPublicIntrospection: ?boolean;
/* Mounts the GraphQL Playground - never use this option in production
/* Mounts the GraphQL Playground which exposes the master key in the browser - never use this option in production
:ENV: PARSE_SERVER_MOUNT_PLAYGROUND
:DEFAULT: false */
mountPlayground: ?boolean;
Expand Down
3 changes: 3 additions & 0 deletions src/ParseServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,9 @@ class ParseServer {

if (options.mountPlayground) {
parseGraphQLServer.applyPlayground(app);
logging.getLogger().warn(
'GraphQL Playground is enabled and exposes the master key in the browser. The playground is a developer tool and should not be used in production. Use Parse Dashboard for production environments.'
);
}
}
const server = await new Promise(resolve => {
Expand Down
12 changes: 12 additions & 0 deletions src/Security/CheckGroups/CheckGroupServerConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ class CheckGroupServerConfig extends CheckGroup {
}
},
}),
new Check({
title: 'GraphQL Playground disabled',
warning:
'GraphQL Playground is enabled and exposes the master key in the browser page.',
solution:
"Change Parse Server configuration to 'mountPlayground: false'. Use Parse Dashboard for GraphQL exploration in production.",
check: () => {
if (config.mountPlayground) {
throw 1;
}
},
}),
new Check({
title: 'Public database explain disabled',
warning:
Expand Down
Loading