fix: authentication bypass and denial of service (DoS) vulnerabilities in Apple Game Center auth adapter (GHSA-qf8x-vqjv-92gr) (#7963)

This commit is contained in:
Manuel
2022-05-01 02:46:57 +02:00
committed by GitHub
parent cd354b77a6
commit 1930a64e9c
2 changed files with 52 additions and 30 deletions

View File

@@ -14,20 +14,16 @@ const authData = {
const { Parse } = require('parse/node');
const crypto = require('crypto');
const https = require('https');
const url = require('url');
const cache = {}; // (publicKey -> cert) cache
function verifyPublicKeyUrl(publicKeyUrl) {
const parsedUrl = url.parse(publicKeyUrl);
if (parsedUrl.protocol !== 'https:') {
try {
const regex = /^https:\/\/(?:[-_A-Za-z0-9]+\.){0,}apple\.com\/.*\.cer$/;
return regex.test(publicKeyUrl);
} catch (error) {
return false;
}
const hostnameParts = parsedUrl.hostname.split('.');
const length = hostnameParts.length;
const domainParts = hostnameParts.slice(length - 2, length);
const domain = domainParts.join('.');
return domain === 'apple.com';
}
function convertX509CertToPEM(X509Cert) {
@@ -40,7 +36,7 @@ function convertX509CertToPEM(X509Cert) {
return pemPreFix + certBody + pemPostFix;
}
function getAppleCertificate(publicKeyUrl) {
async function getAppleCertificate(publicKeyUrl) {
if (!verifyPublicKeyUrl(publicKeyUrl)) {
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
@@ -50,6 +46,25 @@ function getAppleCertificate(publicKeyUrl) {
if (cache[publicKeyUrl]) {
return cache[publicKeyUrl];
}
const url = new URL(publicKeyUrl);
const headOptions = {
hostname: url.hostname,
path: url.pathname,
method: 'HEAD',
};
const headers = await new Promise((resolve, reject) =>
https.get(headOptions, res => resolve(res.headers)).on('error', reject)
);
if (
headers['content-type'] !== 'application/pkix-cert' ||
headers['content-length'] == null ||
headers['content-length'] > 10000
) {
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
`Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`
);
}
return new Promise((resolve, reject) => {
https
.get(publicKeyUrl, res => {