CVE-2022-22117 (JSON, published 2022-01-10T16:15Z)
Description: value: In Directus, versions 9.0.0-alpha.4 through 9.4.1 allow unrestricted file upload of .html files in the media upload functionality, which leads to Cross-Site Scripting vulnerability. A low privileged attacker can upload a crafted HTML file as a profile avatar, and when an admin or another user opens it, the XSS payload gets triggered.
Severity: LOW (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/directus/directus
Files changed:
api/package.json
api/src/app.ts
docs/configuration/config-options.md
package-lock.json
Commit message: Add Content-Security-Policy header by default (#10776)



Vulnerable code:
| Variable                         | Description                                                                                                            | Default Value            |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `KEY`                            | Unique identifier for the project.                                                                                     | --                       |
| `SECRET`                         | Secret string for the project.                                                                                         | --                       |
| `ACCESS_TOKEN_TTL`               | The duration that the access token is valid.                                                                           | `15m`                    |
| `REFRESH_TOKEN_TTL`              | The duration that the refresh token is valid, and also how long users stay logged-in to the App.                       | `7d`                     |
| `REFRESH_TOKEN_COOKIE_DOMAIN`    | Which domain to use for the refresh cookie. Useful for development mode.                                               | --                       |
| `REFRESH_TOKEN_COOKIE_SECURE`    | Whether or not to use a secure cookie for the refresh token in cookie mode.                                            | `false`                  |
| `REFRESH_TOKEN_COOKIE_SAME_SITE` | Value for `sameSite` in the refresh token cookie when in cookie mode.                                                  | `lax`                    |
| `REFRESH_TOKEN_COOKIE_NAME`      | Name of refresh token cookie .                                                                                         | `directus_refresh_token` |
| `PASSWORD_RESET_URL_ALLOW_LIST`  | List of URLs that can be used [as `reset_url` in /password/request](/reference/authentication/#request-password-reset) | --                       |
| `USER_INVITE_URL_ALLOW_LIST`     | List of URLs that can be used [as `invite_url` in /users/invite](/reference/system/users/#invite-a-new-user)           | --                       |
| `IP_TRUST_PROXY`                 | Settings for [express' trust proxy setting](https://expressjs.com/en/guide/behind-proxies.html)                        | true                     |
| `IP_CUSTOM_HEADER`               | What custom request header to use for the IP address                                                                   | false                    |

Fixed code:
		"helmet": "^4.6.0",
import helmet from 'helmet';
import { getConfigFromEnv } from './utils/get-config-from-env';
	app.use(helmet.contentSecurityPolicy(getConfigFromEnv('CONTENT_SECURITY_POLICY_')));

| Variable                         | Description                                                                                                                           | Default Value            |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `KEY`                            | Unique identifier for the project.                                                                                                    | --                       |
| `SECRET`                         | Secret string for the project.                                                                                                        | --                       |
| `ACCESS_TOKEN_TTL`               | The duration that the access token is valid.                                                                                          | `15m`                    |
| `REFRESH_TOKEN_TTL`              | The duration that the refresh token is valid, and also how long users stay logged-in to the App.                                      | `7d`                     |
| `REFRESH_TOKEN_COOKIE_DOMAIN`    | Which domain to use for the refresh cookie. Useful for development mode.                                                              | --                       |
| `REFRESH_TOKEN_COOKIE_SECURE`    | Whether or not to use a secure cookie for the refresh token in cookie mode.                                                           | `false`                  |
| `REFRESH_TOKEN_COOKIE_SAME_SITE` | Value for `sameSite` in the refresh token cookie when in cookie mode.                                                                 | `lax`                    |
| `REFRESH_TOKEN_COOKIE_NAME`      | Name of refresh token cookie .                                                                                                        | `directus_refresh_token` |
| `PASSWORD_RESET_URL_ALLOW_LIST`  | List of URLs that can be used [as `reset_url` in /password/request](/reference/authentication/#request-password-reset)                | --                       |
| `USER_INVITE_URL_ALLOW_LIST`     | List of URLs that can be used [as `invite_url` in /users/invite](/reference/system/users/#invite-a-new-user)                          | --                       |
| `IP_TRUST_PROXY`                 | Settings for [express' trust proxy setting](https://expressjs.com/en/guide/behind-proxies.html)                                       | true                     |
| `IP_CUSTOM_HEADER`               | What custom request header to use for the IP address                                                                                  | false                    |
| `CONTENT_SECURITY_POLICY`        | Custom options for the Content-Security-Policy header. See [helmet's documentation](https://helmetjs.github.io) for more information. | --                       |
				"helmet": "^4.6.0",
		"node_modules/helmet": {
			"version": "4.6.0",
			"resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz",
			"integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg==",
			"engines": {
				"node": ">=10.0.0"
			}
		},
				"helmet": "*",
		"helmet": {
			"version": "4.6.0",
			"resolved": "https://registry.npmjs.org/helmet/-/helmet-4.6.0.tgz",
			"integrity": "sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg=="
		},