Security fix

Replaced all instances of DB .whereRaw with their much safer equivalent
methods.

All previous usages of .whereRaw were vulnerable to SQL injections,
cause we were passing the data directly.

Fortunately, they were only used in API routes that required staff
(moderators included) accounts.

---

Updated dependency:
helmet: 3.21.1 -> 3.21.2
This commit is contained in:
Bobby Wibowo 2019-10-22 10:52:52 +07:00
parent cf8d2895f1
commit 36763c2a77
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
4 changed files with 50 additions and 49 deletions

View File

@ -766,34 +766,29 @@ self.list = async (req, res) => {
}
function filter () {
if (req.params.id !== undefined) {
if (req.params.id !== undefined)
this.where('albumid', req.params.id)
} else if (!all) {
else if (!all)
this.where('userid', user.id)
} else {
else
// Fisrt, look for uploads matching ANY of the supplied 'user' OR 'ip' filters
// Then, refine the matches using the supplied 'name' filters
const raw = []
const source = []
this.where(function () {
if (_filters.uploaders.length)
source.push(`\`userid\` in (${_filters.uploaders.map(v => `'${v.id}'`).join(', ')})`)
this.orWhereIn('userid', _filters.uploaders.map(v => v.id))
if (_filters.ips.length)
source.push(`\`ip\` in (${_filters.ips.map(v => `'${v}'`).join(', ')})`)
this.orWhereIn('ip', _filters.ips)
if (_filters.flags.nouser)
source.push('(`userid` is null or \'\')')
this.orWhereNull('userid')
if (_filters.flags.noip)
source.push('(`ip` is null or \'\')')
if (source.length)
raw.push(`(${source.join(' or ')})`)
if (_filters.names.length)
raw.push(`(${_filters.names.map(v => {
if (v.includes('*'))
return `\`name\` like '${v.replace(/\*/g, '%')}'`
this.orWhereNull('ip')
}).andWhere(function () {
for (const name of _filters.names)
if (name.includes('*'))
this.orWhere('name', 'like', name.replace(/\*/g, '%'))
else
return `\`name\` = '${v}'`
}).join(' or ')})`)
this.whereRaw(raw.join(' and '))
}
this.orWhere('name', name)
})
}
// Query uploads count for pagination

View File

@ -704,12 +704,18 @@ self.stats = async (req, res, next) => {
}
stats.uploads.images = await db.table('files')
.whereRaw(self.imageExts.map(ext => `\`name\` like '%${ext}'`).join(' or '))
.where(function () {
for (const ext of self.imageExts)
this.orWhere('name', 'like', `%${ext}`)
})
.count('id as count')
.then(rows => rows[0].count)
stats.uploads.videos = await db.table('files')
.whereRaw(self.videoExts.map(ext => `\`name\` like '%${ext}'`).join(' or '))
.where(function () {
for (const ext of self.videoExts)
this.orWhere('name', 'like', `%${ext}`)
})
.count('id as count')
.then(rows => rows[0].count)

View File

@ -35,7 +35,7 @@
"express": "^4.17.1",
"express-rate-limit": "^5.0.0",
"fluent-ffmpeg": "^2.1.2",
"helmet": "^3.21.1",
"helmet": "^3.21.2",
"jszip": "^3.2.2",
"knex": "^0.19.5",
"multer": "^1.4.2",

View File

@ -203,9 +203,9 @@
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*":
version "12.11.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.1.tgz#1fd7b821f798b7fa29f667a1be8f3442bb8922a3"
integrity sha512-TJtwsqZ39pqcljJpajeoofYRfeZ7/I/OMUQ5pR4q5wOKf2ocrUvBAZUMhWsOvKx3dVc/aaV5GluBivt0sWqA5A==
version "12.11.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.11.2.tgz#75ba3beda30d690b89a5089ca1c6e8e386150b76"
integrity sha512-dsfE4BHJkLQW+reOS6b17xhZ/6FB1rB8eRRvO08nn5o+voxf3i74tuyFWNH6djdfgX7Sm5s6LD8t6mJug4dpDw==
"@types/q@^1.5.1":
version "1.5.2"
@ -740,7 +740,7 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bowser@^2.6.1:
bowser@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.7.0.tgz#96eab1fa07fab08c1ec4c75977a7c8ddf8e0fe1f"
integrity sha512-aIlMvstvu8x+34KEiOHD3AsBgdrzg6sxALYiukOWhFvGMbQI6TRP/iY0LMhUrHs56aD6P1G0Z7h45PUJaa5m9w==
@ -1817,9 +1817,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.284:
version "1.3.289"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.289.tgz#1f85add5d7086ce95d9361348c26aa9de5779906"
integrity sha512-39GEOWgTxtMDk/WjIQLg4W/l1s4FZdiMCqUBLjd92tAXsBPDFLwuwCba5OGhuTdVYm6E128TZIqSnMpeocUlCQ==
version "1.3.290"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.290.tgz#a3f345abe4f1fb0a2fedf51193f4f4489bb94a82"
integrity sha512-pkKffog2KZ5PPcC8ITNXDpucznLFVVLUS2Us0tBF0Qy9114vzDpgWntvFNE1uYEmMUIrWGFu4rDMHwgQAbNYyQ==
emoji-regex@^7.0.1:
version "7.0.3"
@ -2663,9 +2663,9 @@ glob-watcher@^5.0.3:
object.defaults "^1.1.0"
glob@^7.1.1, glob@^7.1.3:
version "7.1.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
version "7.1.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
@ -3008,20 +3008,20 @@ helmet-crossdomain@0.4.0:
resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz#5f1fe5a836d0325f1da0a78eaa5fd8429078894e"
integrity sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==
helmet-csp@2.9.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.2.tgz#bec0adaf370b0f2e77267c9d8b6e33b34159c1e5"
integrity sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==
helmet-csp@2.9.4:
version "2.9.4"
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.4.tgz#801382bac98f2f88706dc5c89d95c7e31af3a4a9"
integrity sha512-qUgGx8+yk7Xl8XFEGI4MFu1oNmulxhQVTlV8HP8tV3tpfslCs30OZz/9uQqsWPvDISiu/NwrrCowsZBhFADYqg==
dependencies:
bowser "^2.6.1"
bowser "^2.7.0"
camelize "1.0.0"
content-security-policy-builder "2.1.0"
dasherize "2.0.0"
helmet@^3.21.1:
version "3.21.1"
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.21.1.tgz#b0ab7c63fc30df2434be27e7e292a9523b3147e9"
integrity sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==
helmet@^3.21.2:
version "3.21.2"
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.21.2.tgz#7e2a19d5f6d898a77b5d2858e8e4bb2cda59f19f"
integrity sha512-okUo+MeWgg00cKB8Csblu8EXgcIoDyb5ZS/3u0W4spCimeVuCUvVZ6Vj3O2VJ1Sxpyb8jCDvzu0L1KKT11pkIg==
dependencies:
depd "2.0.0"
dns-prefetch-control "0.2.0"
@ -3030,7 +3030,7 @@ helmet@^3.21.1:
feature-policy "0.3.0"
frameguard "3.1.0"
helmet-crossdomain "0.4.0"
helmet-csp "2.9.2"
helmet-csp "2.9.4"
hide-powered-by "1.1.0"
hpkp "2.0.0"
hsts "2.2.0"
@ -4385,9 +4385,9 @@ nocache@2.1.0:
integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
node-abi@^2.7.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.11.0.tgz#b7dce18815057544a049be5ae75cd1fdc2e9ea59"
integrity sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==
version "2.12.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.12.0.tgz#40e9cfabdda1837863fa825e7dfa0b15686adf6f"
integrity sha512-VhPBXCIcvmo/5K8HPmnWJyyhvgKxnHTUMXR/XwGHV68+wrgkzST4UmQrY/XszSWA5dtnXpNp528zkcyJ/pzVcw==
dependencies:
semver "^5.4.1"