From 710dfdcf844b77dbdb3e78f2c5df2c1a45d85ae1 Mon Sep 17 00:00:00 2001 From: TheEssem Date: Thu, 16 Jul 2020 19:53:44 -0500 Subject: [PATCH] Prevent using images larger than 25MB, automatically cancel request after 15 seconds --- package-lock.json | 13 +++++++++++++ package.json | 1 + utils/imagedetect.js | 18 +++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 011b186..dd7a40a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,6 +73,14 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.20.tgz", "integrity": "sha512-MRn/NP3dee8yL5QhbSA6riuwkS+UOcsPUMOIOG3KMUQpuor/2TopdRBu8QaaB4fGU+gz/bzyDWt0FtUbeJ8H1A==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "acorn": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", @@ -843,6 +851,11 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", diff --git a/package.json b/package.json index bcc8799..e4712d7 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "@lavacord/eris": "0.0.3", + "abort-controller": "^3.0.0", "cowsay": "^1.4.0", "cron": "^1.8.2", "dblapi.js": "^2.4.0", diff --git a/utils/imagedetect.js b/utils/imagedetect.js index 6f1f075..11bfb58 100644 --- a/utils/imagedetect.js +++ b/utils/imagedetect.js @@ -1,4 +1,5 @@ const fetch = require("node-fetch"); +const AbortController = require("abort-controller"); const fileType = require("file-type"); const { promisify } = require("util"); const writeFile = promisify(require("fs").writeFile); @@ -8,9 +9,14 @@ const urlRegex = /(?:\w+:)?\/\/(\S+)/; // this checks if the file is, in fact, an image const typeCheck = async (image, image2, gifv = false) => { // download the file to a buffer - const imageRequest = await fetch(image); - const imageBuffer = await imageRequest.buffer(); + const controller = new AbortController(); + const timeout = setTimeout(() => { + controller.abort(); + }, 15000); try { + const imageRequest = await fetch(image, { signal: controller.signal }); + const imageBuffer = await imageRequest.buffer(); + if (imageBuffer.size >= 25 * 1024 * 1024) return; // get the file type const imageType = await fileType.fromBuffer(imageBuffer); // check if the file is a jpeg, png, or webp @@ -33,7 +39,13 @@ const typeCheck = async (image, image2, gifv = false) => { return false; } } catch (error) { - throw error; + if (error.name === "AbortError") { + throw Error("Timed out"); + } else { + throw error; + } + } finally { + clearTimeout(timeout); } };