Skip to content

Commit 095dd8d

Browse files
Delo 4068 cloudinary web speed test server package json remote code execution rce (#61)
* updated deps, minor adjustments and improvements * paackage name change to avoid confusion (https://security.snyk.io/package/npm/pagespeed-server)
1 parent 8b97e62 commit 095dd8d

File tree

6 files changed

+413
-547
lines changed

6 files changed

+413
-547
lines changed

app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ app.use(function (req, res, next) {
1313
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
1414
if ('OPTIONS' === req.method) {
1515
//respond with 200
16-
res.send(200);
16+
res.sendStatus(200);
1717
}
1818
else {
1919
//move on

cloudinary/apiCaller.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const _ = require('lodash');
1111
const cloudinaryParser = require('./cloudinaryResultParser');
1212
const cloudinary = require('cloudinary');
1313
const async = require('async');
14-
const request = require('got');
14+
const got = (...args) => import('got').then(({default: got}) => got(...args));
1515

1616
const sendToAnalyze = (imagesArray, dpr, metaData, quality, cb, rollBarMsg) => {
1717
let batchSize = config.get('cloudinary.batchSize');
@@ -23,7 +23,7 @@ const addServerInfo = (imageList, batchSize, dpr, metaData, quality, cb, rollBar
2323
const list = imageList.filter((el) => el);
2424
let bs = list.length > batchSize ? batchSize : list.length;
2525
async.eachLimit(list, bs, (img, callback) => {
26-
request.head(img.url).then(({headers}) => {
26+
got({method: "HEAD", url: img.url}).then(({headers}) => {
2727
img.server = (headers.server) ? headers.server : 'N/A';
2828
callback();
2929
}).catch((e) => {

package.json

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
{
2-
"name": "pagespeed-server",
2+
"name": "web-speed-test-server",
33
"version": "1.1.2",
44
"private": true,
55
"scripts": {
66
"test": "mocha",
7-
"start": "node start.js"
7+
"start": "node start.js",
8+
"postinstall": "patch-package"
89
},
910
"dependencies": {
1011
"async": "^3.2.4",
1112
"body-parser": "~1.20.2",
1213
"bytes": "^3.1.2",
13-
"cloudinary": "https://github.com/cloudinary/cloudinary_npm.git#analyze_api_legacy",
14+
"cloudinary": "1.41.0",
1415
"config": "^3.3.9",
1516
"cookie-parser": "~1.4.6",
1617
"debug": "~4.3.4",
17-
"dotenv": "^16.1.4",
18+
"dotenv": "^16.3.1",
1819
"express": "~4.18.2",
19-
"got": "^11.8.6",
20+
"got": "^13.0.0",
2021
"lodash": "^4.17.21",
21-
"rollbar": "^2.26.1",
22+
"rollbar": "^2.26.2",
2223
"valid-url": "^1.0.9"
2324
},
2425
"devDependencies": {
25-
"chai": "^4.3.7",
26+
"chai": "^4.3.10",
2627
"chai-http": "^4.4.0",
2728
"husky": "^8.0.3",
2829
"mocha": "^10.2.0",
29-
"nock": "^13.3.1",
30-
"sinon": "^15.1.2",
30+
"nock": "^13.3.3",
31+
"patch-package": "^8.0.0",
32+
"sinon": "^16.1.0",
3133
"sinon-chai": "^3.7.0"
3234
}
3335
}

patches/cloudinary+1.41.0.patch

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
diff --git a/node_modules/cloudinary/lib-es5/utils/index.js b/node_modules/cloudinary/lib-es5/utils/index.js
2+
index 35f9385..76fd24e 100644
3+
--- a/node_modules/cloudinary/lib-es5/utils/index.js
4+
+++ b/node_modules/cloudinary/lib-es5/utils/index.js
5+
@@ -437,7 +437,9 @@ function build_upload_params(options) {
6+
accessibility_analysis: utils.as_safe_bool(options.accessibility_analysis),
7+
use_asset_folder_as_public_id_prefix: utils.as_safe_bool(options.use_asset_folder_as_public_id_prefix),
8+
visual_search: utils.as_safe_bool(options.visual_search),
9+
- on_success: options.on_success
10+
+ on_success: options.on_success,
11+
+ /* for internal use only */
12+
+ analyze: JSON.stringify(options.analyze)
13+
};
14+
return utils.updateable_resource_params(options, params);
15+
}
16+
diff --git a/node_modules/cloudinary/lib/utils/index.js b/node_modules/cloudinary/lib/utils/index.js
17+
index 47acd25..a3ac938 100644
18+
--- a/node_modules/cloudinary/lib/utils/index.js
19+
+++ b/node_modules/cloudinary/lib/utils/index.js
20+
@@ -415,7 +415,9 @@ function build_upload_params(options) {
21+
accessibility_analysis: utils.as_safe_bool(options.accessibility_analysis),
22+
use_asset_folder_as_public_id_prefix: utils.as_safe_bool(options.use_asset_folder_as_public_id_prefix),
23+
visual_search: utils.as_safe_bool(options.visual_search),
24+
- on_success: options.on_success
25+
+ on_success: options.on_success,
26+
+ /* for internal use only */
27+
+ analyze: JSON.stringify(options.analyze)
28+
};
29+
return utils.updateable_resource_params(options, params);
30+
}

wtp/apiCaller.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
const path = require('path');
9-
const got = require('got');
9+
const got = (...args) => import('got').then(({default: got}) => got(...args));
1010
const config = require('config');
1111
const logger = require('../logger');
1212
const log = logger.logger;
@@ -19,12 +19,13 @@ const GET_TEST_STATUS = 'http://www.webpagetest.org/testStatus.php';
1919

2020
const getTestResults = async (testId, quality, cb) => {
2121
let options = {
22+
method: "GET",
2223
url: RESULTS_URL,
2324
searchParams: {test: testId},
2425
headers: { 'User-Agent': 'WebSpeedTest' }
2526
};
2627
try {
27-
const response = await got.get(options)
28+
const response = await got(options)
2829
const {statusCode, body} = response;
2930
let resBody = JSON.parse(body);
3031
let rollBarMsg = {testId: resBody.data.id, analyzedUrl: resBody.data.testUrl, thirdPartyErrorCode: "", file: path.basename((__filename))};
@@ -62,6 +63,7 @@ const runWtpTest = async (url, mobile, cb) => {
6263
const apiKeys = config.get('wtp.apiKey').split(',');
6364
const apiKey = apiKeys[Math.floor(Math.random() * apiKeys.length)];
6465
let options = {
66+
method: "POST",
6567
url: RUN_TEST_URL,
6668
searchParams: {
6769
url: url,
@@ -81,7 +83,7 @@ const runWtpTest = async (url, mobile, cb) => {
8183
let response;
8284
let rollBarMsg = {testId: "", analyzedUrl: url, thirdPartyErrorCode: "", file: path.basename((__filename))};
8385
try {
84-
response = await got.post(options);
86+
response = await got(options);
8587
const {statusCode, body} = response;
8688
if (statusCode !== 200) {
8789
rollBarMsg.thirdPartyErrorCode = response.statusCode;
@@ -112,14 +114,15 @@ const runWtpTest = async (url, mobile, cb) => {
112114

113115
const checkTestStatus = async (testId, quality, cb) => {
114116
let options = {
117+
method: "GET",
115118
url: GET_TEST_STATUS,
116119
searchParams: {test: testId, k: config.get('wtp.apiKey'), f: "json"},
117120
'headers': { 'User-Agent': 'WebSpeedTest' }
118121
};
119122
let response;
120123
let rollBarMsg = {};
121124
try {
122-
response = await got.get(options);
125+
response = await got(options);
123126
const {statusCode, body} = response;
124127
let bodyJson = JSON.parse(body);
125128
rollBarMsg = {testId: testId, thirdPartyErrorCode: "", file: path.basename((__filename))};

0 commit comments

Comments
 (0)