Summary Koa uses an evil regex to parse the X-Forwarded-Proto and X-Forwarded-Host HTTP headers. This can be exploited to carry out a Denial-of-Service attack.
PoC
Coming soon.
Impact This is a Regex Denial-of-Service attack and causes memory exhaustion. The regex should be improved and empty values should not be allowed.
Summary In koa < 2.16.1 and < 3.0.0-alpha.5, passing untrusted user input to ctx.redirect() even after sanitizing it, may execute javascript code on the user who use the app.
Patches This issue is patched in 2.16.1 and 3.0.0-alpha.5.
PoC Coming soon...
Impact 1. Redirect user to another phishing site 2. Make request to another endpoint of the application based on user's cookie 3. Steal user's cookie
Summary In the latest version of Koa, the back method used for redirect operations adopts an insecure implementation, which uses the user-controllable referrer header as the redirect target.
Details on the API document https://www.koajs.net/api/response#responseredirecturl-alt, we can see:
response.redirect(url, [alt]) Performs a [302] redirect to url. The string "back" is specially provided for Referrer support, using alt or "/" when Referrer does not exist.
ctx.redirect('back'); ctx.redirect('back', '/index.html'); ctx.redirect('/login'); ctx.redirect('http://google.com');
however, the "back" method is insecure:
- https://github.com/koajs/koa/blob/master/lib/response.js#L322 back (alt) { const url = this.ctx.get('Referrer') || alt || '/' this.redirect(url) }, Referrer Header is User-Controlled.
PoC
there is a demo for POC: const Koa = require('koa') const serve = require('koa-static') const Router = require('@koa/router') const path = require('path')
const app = new Koa() const router = new Router()
// Serve static files from the public directory app.use(serve(path.join(dirname, 'public')))
// Define routes router.get('/test', ctx => { ctx.redirect('back', '/index1.html') })
router.get('/test2', ctx => { ctx.redirect('back') })
router.get('/', ctx => { ctx.body = 'Welcome to the home page! Try accessing /test, /test2' })
app.use(router.routes()) app.use(router.allowedMethods())
const port = 3000 app.listen(port, () => { console.log(Server running at http://localhost:${port}) }) Proof Of Concept GET /test HTTP/1.1 Host: 127.0.0.1:3000 Referer: http://www.baidu.com Connection: close
GET /test2 HTTP/1.1 Host: 127.0.0.1:3000 Referer: http://www.baidu.com Connection: close !image
!image
Impact https://learn.snyk.io/lesson/open-redirect/