-
Notifications
You must be signed in to change notification settings - Fork 734
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request from GHSA-4852-vrh7-28rf
* fix: security vulnerability allowing XSS reflection with user input * fix: update docs, replace santize-html and sanitizeUrl with xss module
- Loading branch information
Showing
14 changed files
with
447 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# Known Vulnerabilities | ||
|
||
## XSS Reflection Vulnerability | ||
|
||
the origin of the vulnerability is in `renderPlaygroundPage`, found in `graphql-playground-html` | ||
|
||
### Impact | ||
|
||
When using | ||
|
||
- `renderPlaygroundPage()`, | ||
- `koaPlayground()` | ||
- `expressPlayground()` | ||
- `koaPlayground()` | ||
- `lambdaPlayground()` | ||
- any downstream dependents that use these functions | ||
|
||
without sanitization of user input, your application is vulnerable to an XSS Reflecton Attack. This is a serious vulnerability that could allow for exfiltration of data or user credentials, or to disrupt systems. | ||
|
||
### Impacted Packages | ||
|
||
**All versions of these packages are impacted until those specified below**, which are now safe for user defined input: | ||
|
||
- `graphql-playground-html`: **☔ safe** @ `1.6.20` | ||
- `graphql-playground-express` **☔ safe** @ `1.7.15` | ||
- `graphql-playground-koa` **☔ safe** @ `1.6.14` | ||
- `graphql-playground-hapi` **☔ safe** @ `1.6.12` | ||
- `graphql-playground-lambda` **☔ safe** @ `1.7.16` | ||
|
||
### Static input was always safe | ||
|
||
These examples are safe for _all versions_ **because input is static** | ||
|
||
with `express` and `renderPlaygroundPage`: | ||
|
||
```js | ||
app.get('/playground', (req) => { | ||
res.html( | ||
renderPlaygroundPage({ | ||
endpoint: `/our/graphql`, | ||
}), | ||
) | ||
next() | ||
}) | ||
``` | ||
|
||
with `expressPlayground`: | ||
|
||
```js | ||
// params | ||
app.get('/playground', (req) => | ||
expressPlayground({ | ||
endpoint: `/our/graphql`, | ||
settings: { 'editor.theme': req.query.darkMode ? 'dark' : 'light' }, | ||
}), | ||
) | ||
``` | ||
|
||
with `koaPlayground`: | ||
|
||
```js | ||
const koa = require('koa') | ||
const koaRouter = require('koa-router') | ||
const koaPlayground = require('graphql-playground-middleware-koa') | ||
|
||
const app = new koa() | ||
const router = new koaRouter() | ||
|
||
router.all('/playground', koaPlayground({ endpoint: '/graphql' })) | ||
``` | ||
|
||
### Vulnerable Examples | ||
|
||
Here are some examples where the vulnerability would be present before the patch, because of unfiltered user input | ||
|
||
```js | ||
const express = require('express') | ||
const expressPlayground = require('graphql-playground-middleware-express') | ||
.default | ||
|
||
const app = express() | ||
|
||
app.use(express.json()) | ||
|
||
// params | ||
app.get('/playground/:id', (req) => | ||
expressPlayground({ | ||
endpoint: `/our/graphql/${req.params.id}`, | ||
}), | ||
) | ||
|
||
// params | ||
app.get('/playground', (req) => | ||
expressPlayground({ | ||
endpoint: `/our/graphql`, | ||
// any settings that are unsanitized user input, not just `endpoint` | ||
settings: { 'editor.fontFamily': req.query.font }, | ||
}), | ||
) | ||
``` | ||
|
||
### Workaround | ||
|
||
To fix this issue without the update, you can sanitize however you want. | ||
|
||
We suggest using [`xss`](https://www.npmjs.com/package/xss) (what we use for our own fix) | ||
|
||
For example, with `graphql-playground-middleware-express`: | ||
|
||
```js | ||
const express = require('express') | ||
const { filterXSS } = require('xss') | ||
const expressPlayground = require('graphql-playground-middleware-express') | ||
.default | ||
|
||
|
||
const app = express() | ||
|
||
const filter = (val) => filterXSS(val, { | ||
whitelist: [], | ||
stripIgnoreTag: true, | ||
stripIgnoreTagBody: ['script'] | ||
}) | ||
|
||
// simple example | ||
app.get('/playground/:id', (req) => | ||
expressPlayground({ endpoint: `/graphql/${filter(req.params.id)}` }) | ||
|
||
// advanced params | ||
app.get('/playground', (req) => | ||
expressPlayground(JSON.parse(filter(JSON.stringify(req.query)))) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,5 +33,7 @@ | |
"typescript": { | ||
"definition": "dist/index.d.ts" | ||
}, | ||
"dependencies": {} | ||
"dependencies": { | ||
"xss": "^1.0.6" | ||
} | ||
} |
Oops, something went wrong.