add tests for unwanted 500 responses from invalid urls (#19612)

* add acceptance tests for bad urls

* fix 500 from health check when smoke test userId is undefined

* handle exception from invalid urls in ExpressLocals middleware

* Add return statement before `next()`

* Cleaned up list of crash_test_urls.txt

* Return 400 instead of 404 on parsing errors

---------

Co-authored-by: mserranom <mserranom@gmail.com>
GitOrigin-RevId: dac35b07d1f12bd9ceb70e3064ec2ef8393f99b5
This commit is contained in:
Brian Gough 2024-08-13 15:08:17 +01:00 committed by Copybot
parent ca802eab82
commit cf83990459
4 changed files with 232 additions and 4 deletions

View file

@ -45,6 +45,10 @@ module.exports = {
logger.err({ err }, 'failed api redis health check')
return res.sendStatus(500)
}
if (!settings.smokeTest.userId) {
logger.err({}, 'smokeTest.userId is undefined in health check')
return res.sendStatus(404)
}
UserGetter.getUserEmail(settings.smokeTest.userId, (err, email) => {
if (err) {
logger.err({ err }, 'failed api mongo health check')

View file

@ -11,6 +11,7 @@ const Features = require('./Features')
const SessionManager = require('../Features/Authentication/SessionManager')
const PackageVersions = require('./PackageVersions')
const Modules = require('./Modules')
const Errors = require('../Features/Errors/Errors')
const {
canRedirectToAdminDomain,
hasAdminAccess,
@ -228,10 +229,14 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
// Don't include the query string parameters, otherwise Google
// treats ?nocdn=true as the canonical version
const parsedOriginalUrl = new URL(req.originalUrl, Settings.siteUrl)
res.locals.currentUrl = parsedOriginalUrl.pathname
res.locals.currentUrlWithQueryParams =
parsedOriginalUrl.pathname + parsedOriginalUrl.search
try {
const parsedOriginalUrl = new URL(req.originalUrl, Settings.siteUrl)
res.locals.currentUrl = parsedOriginalUrl.pathname
res.locals.currentUrlWithQueryParams =
parsedOriginalUrl.pathname + parsedOriginalUrl.search
} catch (err) {
return next(new Errors.InvalidError())
}
res.locals.capitalize = function (string) {
if (string.length === 0) {
return ''

View file

@ -0,0 +1,192 @@
//
///%09/example.com
//%0D%0ASet-Cookie:crlfinjection=crlfinjection
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd/
///////%20../%20../%20../%20../%20../%20../etc%2fpasswd
///////%20../%20../%20../%20../%20../%20../etc%2fpasswd/
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd%23vt/test
///////%20../%20../%20../%20../%20../%20../etc%2fpasswd%23vt/test
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd/
///////%20../%20../%20../%20../%20../%20../etc%5cpasswd
///////%20../%20../%20../%20../%20../%20../etc%5cpasswd/
///////%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd%23vt/test
///////%20../%20../%20../%20../%20../%20../etc%5cpasswd%23vt/test
///////%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd
///////%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd/
///////%20../%20../%20../%20../%20../%20../etc/passwd
///////%20../%20../%20../%20../%20../%20../etc/passwd/
///////%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd%23vt/test
///////%20../%20../%20../%20../%20../%20../etc/passwd%23vt/test
///////%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd
///////%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd/
///////%20../%20../%20../%20../%20../%20../etc\x5Cpasswd
///////%20../%20../%20../%20../%20../%20../etc\x5Cpasswd/
///////%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd%23vt/test
///////%20../%20../%20../%20../%20../%20../etc\x5Cpasswd%23vt/test
//%2509/example.com
///%2509/example.com
////%2509/example.com
//%250d%250ahttp://example.com/
//.%25%2532%2565/.%25%2532%2565/.%25%2532%2565/.%25%2532%2565/.%25%2532%2565/.%25%2532%2565/.%25%2532%2565/windows/win.ini
//.%252e/.%252e/.%252e/.%252e/.%252e/.%252e/.%252e/etc/passwd
//.%252e/.%252e/.%252e/.%252e/.%252e/.%252e/.%252e/windows/win.ini
//%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini
//..%255C../..%255C../..%255C../..%255C../..%255C../..%255C../etc/profile
//%255cexample.com
///%255cexample.com
////%255cexample.com
//%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/%25c0%25ae%25c0%25ae/etc/profile
//..%25c0%25af../..%25c0%25af../..%25c0%25af../..%25c0%25af../..%25c0%25af../..%25c0%25af../etc/profile
//%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cetc/passwd
//%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cwindows/win.ini
//.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./etc/passwd
//.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./.%5C%5C./windows/win.ini
//%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
//%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../windows/win.ini
//%5c../%5c../%5c../%5c../%5c../%5c../%5c../etc/passwd
//..%5c..%5c..%5c..%5c..%5c..%5c..%5cetc/passwd
//..%5c..%5c..%5c..%5c..%5c..%5cetc/passwd
//..%5c..%5c..%5c..%5c..%5cetc/passwd
//..%5c..%5c..%5c..%5cetc/passwd
//..%5c..%5c..%5cetc/passwd
//..%5c..%5cetc/passwd
//..%5cetc/passwd
//%5cexample.com
////%5cexample.com
//?AaauA=olihQ
//%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
//%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini
//%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
//%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini
//%c0%ae/%c0%ae/%c0%ae/%c0%ae/WEB-INF/web.xml
//%c0%ae/%c0%ae/%c0%ae/WEB-INF/web.xml
//%c0%ae/%c0%ae/WEB-INF/web.xml
//%c0%ae/WEB-INF/web.xml
//.env.150
//.env.34.213
//////////etc%2fpasswd
//////////etc%2fpasswd/
/////////etc%2fpasswd
/////////etc%2fpasswd/
////////etc%2fpasswd
////////etc%2fpasswd/
////etc%2fpasswd
////etc%2fpasswd/
///etc%2fpasswd
///etc%2fpasswd/
//etc%2fpasswd
//etc%2fpasswd/
//////////etc%2fpasswd%23vt/test
/////////etc%2fpasswd%23vt/test
////////etc%2fpasswd%23vt/test
////etc%2fpasswd%23vt/test
///etc%2fpasswd%23vt/test
//etc%2fpasswd%23vt/test
//////////etc%5cpasswd
//////////etc%5cpasswd/
/////////etc%5cpasswd
/////////etc%5cpasswd/
////////etc%5cpasswd
////////etc%5cpasswd/
////etc%5cpasswd
////etc%5cpasswd/
///etc%5cpasswd
///etc%5cpasswd/
//etc%5cpasswd
//etc%5cpasswd/
//////////etc%5cpasswd%23vt/test
/////////etc%5cpasswd%23vt/test
////////etc%5cpasswd%23vt/test
////etc%5cpasswd%23vt/test
///etc%5cpasswd%23vt/test
//etc%5cpasswd%23vt/test
//example%2500.com
//example%25E3%2580%2582com
//https%253a//example.com//
//https%253a///example.com/%252e%252e
//https%253a//example.com/%252e%252e%252f
//https%3a//example.com/%2e%2e%2f
//https%3a//example.com/..%2f
//overleaf.example.com.443/libs/cq/contentinsight/content/proxy.reportingservices.json;%0a.html?url=http://overleaf.example.com.443.lcccprjn.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/content/proxy.reportingservices.json/a.ico?url=http://overleaf.example.com.443.lcccpru.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs///cq///contentinsight///content///proxy.reportingservices.json?url=http://overleaf.example.com.443.lcccccc.mk7.xyz%23/api1.omniture.com/a&q=a&.css
//overleaf.example.com.443/libs/cq/contentinsight/content/proxy.reportingservices.json?url=http://overleaf.example.com.443.lcccpr.mk7.xyz%23/api1.omniture.com/a&q=a&.css
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet;%0a.html?url=http://overleaf.example.com.443.lccprjnu.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet.a.21.css?url=http://overleaf.example.com.443.lccprcu.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443//libs/cq/contentinsight/proxy/reportingservices.json.get.servlet.a.21.css?url=http://overleaf.example.com.443.llccprj.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet/a.ico?url=http://overleaf.example.com.443.lccpr.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet.css?url=http://overleaf.example.com.443.lccpruc.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet.html?url=http://overleaf.example.com.443.lccpruh.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet.ico?url=http://overleaf.example.com.443.lccpri.mk7.xyz%23/api1.omniture.com/a&q=a
//overleaf.example.com.443/libs///cq///contentinsight///proxy///reportingservices.json.get.servlet?url=http://overleaf.example.com.443.lccprjg.mk7.xyz%23/api1.omniture.com/a&q=a&.css
//overleaf.example.com.443/libs/cq/contentinsight/proxy/reportingservices.json.get.servlet?url=http://overleaf.example.com.443.lccpr.mk7.xyz%23/api1.omniture.com/a&q=a&.css
//overleaf.example.com.443/libs/mcm/salesforce/customer/a.ico?checktype=authorize&authorization_url=http://overleaf.example.com.443.lmscaic.mk7.xyz&customer_key=zzzz&customer_secret=zzzz&redirect_uri=xxxx&code=e
//overleaf.example.com.443/libs/mcm/salesforce/customer?checktype=authorize&authorization_url=http://overleaf.example.com.443.lmscc.mk7.xyz&customer_key=zzzz&customer_secret=zzzz&redirect_uri=xxxx&code=e&.css
//overleaf.example.com.443/libs/mcm/salesforce/customer.html;%0aa.css?checktype=authorize&authorization_url=http://overleaf.example.com.443.lmsmn.mk7.xyz&customer_key=zzzz&customer_secret=zzzz&redirect_uri=xxxx&code=e
//overleaf.example.com.443/libs/opensocial/makerequest;%0a.html?container=default&url=http://overleaf.example.com.443.lomnh.mk7.xyz/os/omn
//overleaf.example.com.443/libs/opensocial/makerequest/a.ico?container=default&url=http://overleaf.example.com.443.lomai.mk7.xyz/os/aim
//overleaf.example.com.443/libs///opensocial///makerequest?container=default&url=http://overleaf.example.com.443.lomcd.mk7.xyz/&.css
//overleaf.example.com.443/libs/opensocial/makerequest?container=default&url=http://overleaf.example.com.443.lomc.mk7.xyz/&.css
//overleaf.example.com.443/plugins/servlet/issue-retriever?columns=summary&url=http://overleaf.example.com.443.psic.mk7.xyz/os/aba
//overleaf.example.com.443/rest/sharelinks/1.0/link?url=http://overleaf.example.com.443.rsol.mk7.xyz/os/ros
//ozTaSrMQ%22%3E%3Cimg%20src=a%20onerror=alert%28document.domain%29%3E/..CFIDE/administrator/index.cfm
//ozTaSrMQ%22%3E%3Cimg%20src=a%20onerror=alert%28document.domain%29%3E/..CFIDE/wizards/common/_authenticatewizarduser.cfm
//ozTaSrMQ%22%3E%3Cscript%3Ealert%28document.domain%29%3C/script%3E/..CFIDE/administrator/index.cfm
//ozTaSrMQ%22%3E%3Cscript%3Ealert%28document.domain%29%3C/script%3E/..CFIDE/wizards/common/_authenticatewizarduser.cfm
//?page=..%2f..%2f..%2f..%2f..%2fwindows/win.ini
//?__proto__%5Bsssied%5D=sssieda&__proto__.sssied=sssiedb&constructor.prototype.sssied=sssiedc&constructor%5Bprototype%5D%5Bsssied%5D=sssiedd&x.__proto__.sssied=sssiede&x%5B__proto__%5D%5Bsssied%5D=sssiedf&x.constructor.prototype.sssied=sssiedg&x%5Bconstructor%5D%5Bprototype%5D%5Bsssied%5D=sssiedh
//proxy.stream%3Forigin=http://overleaf.example.com.443.ppsto.mk7.xyz
//qNAViNxG%22%3E%3Cimg%20src=a%20onerror=alert%28document.domain%29%3E/..CFIDE/administrator/index.cfm
//qNAViNxG%22%3E%3Cimg%20src=a%20onerror=alert%28document.domain%29%3E/..CFIDE/wizards/common/_authenticatewizarduser.cfm
//qNAViNxG%22%3E%3Cscript%3Ealert%28document.domain%29%3C/script%3E/..CFIDE/administrator/index.cfm
//qNAViNxG%22%3E%3Cscript%3Ealert%28document.domain%29%3C/script%3E/..CFIDE/wizards/common/_authenticatewizarduser.cfm
//?redirect=..%2f..%2f..%2f..%2fwindows/win.ini
//?url=..%2f..%2f..%2f..%2f..%2f..%2fwindows/win.ini
/\x5Cu001B]8;;https://interact.sh\x22/onmouseover=\x22alert(1)\x5Cu0007example\x5Cu001B]8;;\x5Cu0007
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%2fpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%2fpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%2fpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%2fpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%5cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%5cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc%5cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc%5cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc/passwd
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc/passwd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc/passwd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc/passwd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc\x5Cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc\x5Cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C%20.../%20.../%20.../%20.../%20.../%20.../etc\x5Cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C%20../%20../%20../%20../%20../%20../etc\x5Cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%2fpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%2fpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%2fpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%2fpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%2fpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%2fpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%2fpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%2fpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%2fpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%5cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%5cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%5cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%5cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%5cpasswd
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%5cpasswd/
/\x5C\x5C\x5C\x5C\x5C\x5C///etc%5cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C//etc%5cpasswd%23vt/test
/\x5C\x5C\x5C\x5C\x5C\x5C/etc%5cpasswd%23vt/test
//?sssieddparamNamexsx=dummy&address=sssieddaddressxsx&redirect=sssieddredirectxsx&userid=sssiedduseridxsx
//?sssieddparamNamexsx=dummy&address=sssieddaddressxsx&tags=sssieddtagsxsx&feed=sssieddfeedxsx&stage=sssieddstagexsx&level=sssieddlevelxsx&activate=sssieddactivatexsx&state=sssieddstatexsx&confirm=sssieddconfirmxsx&utm_campaign=sssieddutm_campaignxsx&visible=sssieddvisiblexsx&linkurl=sssieddlinkurlxsx&request=sssieddrequestxsx&all=sssieddallxsx&return_url=sssieddreturn_urlxsx&SAMLRequest=sssieddSAMLRequestxsx&src=sssieddsrcxsx&cmd=sssieddcmdxsx&Referer=sssieddRefererxsx&image_host=sssieddimage_hostxsx&cancel=sssieddcancelxsx&end=sssieddendxsx&group=sssieddgroupxsx&uuid=sssiedduuidxsx&short=sssieddshortxsx&version=sssieddversionxsx
//?sssieddparamNamexsx=dummy&add=sssieddaddxsx&address=sssieddaddressxsx&log=sssieddlogxsx&step=sssieddstepxsx&reset=sssieddresetxsx&checked=sssieddcheckedxsx&other=sssieddotherxsx&settings=sssieddsettingsxsx&meta=sssieddmetaxsx&message=sssieddmessagexsx&dir=sssiedddirxsx&pass=sssieddpassxsx&issues=sssieddissuesxsx&from=sssieddfromxsx&parent=sssieddparentxsx&f=sssieddfxsx&ref=sssieddrefxsx&color=sssieddcolorxsx&fetch=sssieddfetchxsx&users=sssieddusersxsx&content=sssieddcontentxsx&generate=sssieddgeneratexsx&admin=sssieddadminxsx&msg=sssieddmsgxsx&URL=sssieddURLxsx

View file

@ -0,0 +1,27 @@
const { expect } = require('chai')
const fs = require('fs')
const Path = require('path')
const fetch = require('node-fetch')
const UserHelper = require('./helpers/UserHelper')
const BASE_URL = UserHelper.baseUrl()
const CRASH_TEST_URLS = fs
.readFileSync(Path.join(__dirname, '../files/crash_test_urls.txt'))
.toString()
.split('\n')
describe('Server Crash Tests', function () {
it(`should not crash on bad urls`, async function () {
// increase the timeout for this test due to the number of urls
this.timeout(60 * 1000)
// test each url in the list
for (let i = 0; i < CRASH_TEST_URLS.length; i++) {
const url = BASE_URL + CRASH_TEST_URLS[i]
const response = await fetch(url)
expect(response.status).to.not.match(
/5\d\d/,
`Request to ${url} failed with status ${response.status}`
)
}
})
})