From e86421240d8a899a8eb626a552225b69f2a8e00c Mon Sep 17 00:00:00 2001 From: MICHAEL JACKSON Date: Fri, 18 Aug 2017 14:43:06 -0700 Subject: [PATCH] Redirect requests with invalid query params to cache --- server/middleware/parsePackageURL.js | 34 ++++++++++++++++++++++++++++ server/middleware/serveFile.js | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/server/middleware/parsePackageURL.js b/server/middleware/parsePackageURL.js index 48ed043..f0345cc 100644 --- a/server/middleware/parsePackageURL.js +++ b/server/middleware/parsePackageURL.js @@ -1,6 +1,32 @@ +const qs = require('querystring') const validateNPMPackageName = require('validate-npm-package-name') const PackageURL = require('../PackageURL') +const KnownQueryParams = { + json: true, // deprecated + main: true, + meta: true +} + +function isKnownQueryParam(param) { + return !!KnownQueryParams[param] +} + +function queryIsKnown(query) { + return Object.keys(query).every(isKnownQueryParam) +} + +function sanitizeQuery(query) { + const saneQuery = {} + + Object.keys(query).forEach(function (param) { + if (isKnownQueryParam(param)) + saneQuery[param] = query[param] + }) + + return saneQuery +} + /** * Parse and validate the URL. */ @@ -16,6 +42,14 @@ function parsePackageURL(req, res, next) { if (nameErrors) return res.status(403).type('text').send(`Invalid package name: ${url.packageName} (${nameErrors.join(', ')})`) + // Redirect requests with unknown query params to their equivalents + // with only known params so they can be served from the cache. This + // prevents people using random query params designed to bust the cache. + if (!queryIsKnown(url.query)) { + const search = qs.stringify(sanitizeQuery(url.query)) + return res.redirect(url.pathname + (search ? `?${search}` : '')) + } + req.packageName = url.packageName req.packageVersion = url.packageVersion req.packageSpec = `${req.packageName}@${req.packageVersion}` diff --git a/server/middleware/serveFile.js b/server/middleware/serveFile.js index 4ff749c..0f11535 100644 --- a/server/middleware/serveFile.js +++ b/server/middleware/serveFile.js @@ -41,7 +41,7 @@ function serveFile(req, res, next) { delete req.query.meta delete req.query.json const search = qs.stringify(req.query) - res.status(301).redirect(`/_meta${req.pathname}${search}`) + res.redirect(`/_meta${req.pathname}${search}`) } else if (req.stats.isFile()) { // Cache files for 1 year. res.set({