Skip to content

Commit

Permalink
fix: Validate push notification payload; fixes a security vulnerabili…
Browse files Browse the repository at this point in the history
…ty in which the adapter can crash Parse Server due to an invalid push notification payload (#217)
  • Loading branch information
mtrezza authored May 20, 2023
1 parent 346781d commit 598cb84
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
26 changes: 20 additions & 6 deletions spec/APNS.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('APNS', () => {

var prodApnsConnection = apns.providers[0];
expect(prodApnsConnection.index).toBe(0);

// TODO: Remove this checking onec we inject APNS
var prodApnsOptions = prodApnsConnection.client.config;
expect(prodApnsOptions.cert).toBe(args[1].cert);
Expand Down Expand Up @@ -239,7 +239,7 @@ describe('APNS', () => {
expect(notification.pushType).toEqual('alert');
done();
});

it('can generate APNS notification from raw data', (done) => {
//Mock request data
let data = {
Expand All @@ -259,17 +259,17 @@ describe('APNS', () => {
let collapseId = "collapseIdentifier";
let pushType = "background";
let priority = 5;

let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId, pushType: pushType, priority: priority });

expect(notification.expiry).toEqual(Math.round(expirationTime / 1000));
expect(notification.collapseId).toEqual(collapseId);
expect(notification.pushType).toEqual(pushType);
expect(notification.priority).toEqual(priority);

let stringifiedJSON = notification.compile();
let jsonObject = JSON.parse(stringifiedJSON);

expect(jsonObject.aps.alert).toEqual({ "loc-key" : "GAME_PLAY_REQUEST_FORMAT", "loc-args" : [ "Jenna", "Frank"] });
expect(jsonObject.aps.badge).toEqual(100);
expect(jsonObject.aps.sound).toEqual('test');
Expand Down Expand Up @@ -315,6 +315,20 @@ describe('APNS', () => {
done();
});

it('does log on invalid APNS notification', async () => {
const args = {
cert: new Buffer('testCert'),
key: new Buffer('testKey'),
production: true,
topic: 'topic'
};
const log = require('npmlog');
const spy = spyOn(log, 'warn');
const apns = new APNS(args);
apns.send();
expect(spy).toHaveBeenCalled();
});

it('can send APNS notification', (done) => {
let args = {
cert: new Buffer('testCert'),
Expand Down
10 changes: 9 additions & 1 deletion spec/GCM.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function mockSender(gcm) {
{"error":"InvalidRegistration"},
{"error":"InvalidRegistration"},
{"error":"InvalidRegistration"}] }*/

let tokens = options.registrationTokens;
const response = {
multicast_id: 7680139367771848000,
Expand Down Expand Up @@ -58,6 +58,14 @@ describe('GCM', () => {
done();
});

it('does log on invalid APNS notification', async () => {
const log = require('npmlog');
const spy = spyOn(log, 'warn');
const gcm = new GCM({apiKey: 'apiKey'});
gcm.send();
expect(spy).toHaveBeenCalled();
});

it('can generate GCM Payload without expiration time', (done) => {
//Mock request data
var requestData = {
Expand Down
6 changes: 5 additions & 1 deletion src/APNS.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ export class APNS {
* @returns {Object} A promise which is resolved immediately
*/
send(data, allDevices) {
let coreData = data.data;
let coreData = data && data.data;
if (!coreData || !allDevices || !Array.isArray(allDevices)) {
log.warn(LOG_PREFIX, 'invalid push payload');
return;
}
let expirationTime = data['expiration_time'] || coreData['expiration_time'];
let collapseId = data['collapse_id'] || coreData['collapse_id'];
let pushType = data['push_type'] || coreData['push_type'];
Expand Down
4 changes: 4 additions & 0 deletions src/GCM.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ GCM.GCMRegistrationTokensMax = GCMRegistrationTokensMax;
* @returns {Object} A promise which is resolved after we get results from gcm
*/
GCM.prototype.send = function(data, devices) {
if (!data || !devices || !Array.isArray(devices)) {
log.warn(LOG_PREFIX, 'invalid push payload');
return;
}
let pushId = randomString(10);
// Make a new array
devices=devices.slice(0);
Expand Down

0 comments on commit 598cb84

Please sign in to comment.