No redirect_uri in the db for web-internal clientKey leads to one-click DoS on gitter.im
Low
G
GitLab
Submitted None
Actions:
Reported by
gregxsunday
Vulnerability Details
Technical details and impact analysis
### Summary
In the *oauthclients* collection of the default gitter installation, there's no value *registeredRedirectUri* in the database for *web-internal* clientKey. The request to
```
/login/oauth/authorize?response_type=code&client_id=web-internal&redirect_uri=http://whatever
```
causes the app to crash when trying to parse the *client.registeredRedirectUri*, which in this situation becomes the value *undefined*.
### Steps to reproduce
1. deploy the standard installation of the gitter application
2. make the GET request to
```
http://localhost:5000/login/oauth/authorize?response_type=code&client_id=web-internal&redirect_uri=http://whatever
```
### Impact
The application crashes and does not wake up on its own.
```
2019-09-27T13:01:09.013Z - error: Uncaught exceptionTypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined forcing shutdown
[15:01:09] [nodemon] app crashed - waiting for file changes before starting...
```
### What is the current *bug* behavior?
When the request to
```
/login/oauth/authorize?response_type=code&client_id=web-internal&redirect_uri=http://whatever
```
is made, the database lookup is being done:
```
oauthService.findClientByClientKey(clientKey, function(err, client) {
if (err) {
return done(err);
}
```
*those are the lines 127-130 from server/web/oauth2.js*
The clientKey is *web-internal*, its record in the Mongo looks like this:
```
{
"_id": ObjectID("5d8453d62edc221c1e5a2f6c"),
"clientKey": "web-internal",
"clientSecret": <clientSecret>,
"name": "Web Client",
"tag": "web-app"
}
```
The query returned something, so the following check is being passed:
```
if (!client) {
return done(new OauthAuthorizationError('Provided clientKey does not exist.'));
}
```
*those are the lines 132-134 from server/web/oauth2.js*
Then, in the 136th line there's parsing that is the root cause of the problem:
```
const urlData = url.parse(client.registeredRedirectUri);
```
as the *client.registeredRedirectUri* is undefined, it throws the *Uncaught exceptionTypeError*.
```
2019-09-27T13:01:09.011Z - error: ----------------------------------------------------------------
2019-09-27T13:01:09.011Z - error: -- A VeryBadThing has happened.
2019-09-27T13:01:09.011Z - error: ----------------------------------------------------------------
2019-09-27T13:01:09.012Z - error: Uncaught exceptionTypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
{ message:
'The "url" argument must be of type string. Received type undefined',
name: 'TypeError [ERR_INVALID_ARG_TYPE]' }
2019-09-27T13:01:09.012Z - error: TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
```
### What is the expected *correct* behavior?
The app should not crash on such error. To mitigate the issue you can
1. simply catch the error
2. add *registeredRedirectUri* to the database record. It can be done by adding a line to *scripts/dataupgrades/001-oauth-client/002-add-redirect-uri.sh* which currently looks like this:
```
db.oauthclients.update(
{ clientKey: 'web-internal' },
{ clientKey: 'web-internal',
clientSecret: '$(generate_password)',
name: 'Web Client',
tag: 'web-app',
}, true /* upsert */);
```
### Relevant logs and/or screenshots
```
019-09-27T13:01:09.006Z - error: No error reporting is enabled so just logging to logger:
{ exception:
{ message:
'The "url" argument must be of type string. Received type undefined',
stack:
'TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined\n at Url.parse (url.js:154:11)\n at Object.urlParse [as parse] (url.js:148:13)\n at /home/gniedziela/projects/gitlab/gitter/webapp/server/web/oauth2.js:137:27\n at tryCatcher (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/util.js:16:23)\n at Promise.successAdapter [as _fulfillmentHandler0] (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/nodeify.js:23:30)\n at Promise._settlePromise (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:566:21)\n at Promise._settlePromise0 (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:614:10)\n at Promise._settlePromises (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:693:18)\n at Async._drainQueue (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:133:16)\n at Async._drainQueues (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:143:10)\n at Immediate.Async.drainQueues (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:17:14)\n at runCallback (timers.js:705:18)\n at tryOnImmediate (timers.js:676:5)\n at processImmediate (timers.js:658:5)\n at process.topLevelDomainCallback (domain.js:126:23)',
name: 'TypeError [ERR_INVALID_ARG_TYPE]' },
meta:
{ errorString:
'TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined',
type: 'uncaught' },
tags:
{ host: 'c7caee1658e769b17e9c1e0e254cb54939a3e982', job: 'web' } }
2019-09-27T13:01:09.011Z - error: ----------------------------------------------------------------
2019-09-27T13:01:09.011Z - error: -- A VeryBadThing has happened.
2019-09-27T13:01:09.011Z - error: ----------------------------------------------------------------
2019-09-27T13:01:09.012Z - error: Uncaught exceptionTypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
{ message:
'The "url" argument must be of type string. Received type undefined',
name: 'TypeError [ERR_INVALID_ARG_TYPE]' }
2019-09-27T13:01:09.012Z - error: TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
at Url.parse (url.js:154:11)
at Object.urlParse [as parse] (url.js:148:13)
at /home/gniedziela/projects/gitlab/gitter/webapp/server/web/oauth2.js:137:27
at tryCatcher (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/util.js:16:23)
at Promise.successAdapter [as _fulfillmentHandler0] (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/nodeify.js:23:30)
at Promise._settlePromise (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:566:21)
at Promise._settlePromise0 (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/home/gniedziela/projects/gitlab/gitter/webapp/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
at process.topLevelDomainCallback (domain.js:126:23)
2019-09-27T13:01:09.013Z - error: Uncaught exceptionTypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined forcing shutdown
[15:01:09] [nodemon] app crashed - waiting for file changes before starting...
```
## Impact
Complete Denial of Service of the Gitter installation.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Uncontrolled Resource Consumption