This patch adds an own filename function for `formidable`, which will
make sure to generate a random file name, using UUIDv4. This should
resolve GHSA-q6vv-2q26-j7rx.
This change is required due to a change in behaviour from version 1 to
version 2 of formidable. Formidable version 2 will generate predictable
filenames by default, which results in potential access to images, that
were uploaded while formidable v2 was used in Hedgedoc. This affects the
versions `1.9.1` and `1.9.2`.
Files generated previous to this commit will look like this:
```
<random string generated on app start><counter>.<file-extension>
38e56506ec2dcab52e9282c00.jpg
38e56506ec2dcab52e9282c01.jpg
38e56506ec2dcab52e9282c02.jpg
```
After this patch it'll look like this:
```
<uuid v4>.<file-extension>
a67f36b8-9afb-43c2-9ef2-a567a77d8628.jpg
56b3d5d0-c586-4679-9ae6-d2044843c2cd.jpg
2af727ac-a2d4-4aad-acb5-73596c2a7eb6.jpg
```
This patch was implemented using `uuid` since we already utilise this
package elsewhere in the project as well as using a secure function to
generate random strings. UUIDv4 is ideal for that. In order to be
consumable by formidable, it was wrapped in a function that makes sure
to keep the file extension.
This vulnerability was reported by Matias from [NCSC-FI](https://www.kyberturvallisuuskeskus.fi/).
References:
https://github.com/node-formidable/formidable/blob/v2-latest/src/Formidable.js#L574https://github.com/node-formidable/formidable/issues/808#issuecomment-1007090762https://www.npmjs.com/package/uuid
Using `CMD_SAML_PROVIDERNAME` and the respective auth provider objects
in the configuration structures.
Signed-off-by: Moritz Schlarb <schlarbm@uni-mainz.de>
The usage of identicons makes users more distinguishable as when only the default librvatar image is used.
This only applies to users that have no avatar on libravatar or gravatar.
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
We use the attribute `emails` (plural) for email addresses with other auth providers like LDAP or SAML. In case of OAuth2 we used the attribute `email` (singular) which resulted in problems.
Furthermore the OAuth2 strategy fell into the default fallback of the provider switch statement. This statement did not check email addresses but did generate the letter-avatar instantly.
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit changes the
- default-src to none, so everything is disallowed by default
- base-uri, connect-uri and font-src to self,
so these are restricted to the current origin
- frame-src to allow SlideShare, Vimeo and YouTube
- script-src to the specific paths that are used by HedgeDoc to serve scripts.
This explicitly does not include the /uploads route
- style-src to the specific paths that are used by HedgeDoc to serve styles
-
Signed-off-by: David Mehren <git@herrmehren.de>
This patch fixes the swollowing of the actual error message that appears
when a file fails to move, after being uploaded to Hedgedoc on an
instance that is using the upload-method `filesystem` active.
This became apparent when the error messages provided by some users,
where less than helpful.
As a solution the error message of the copy command was added to the
error that is output to the console.
https://community.hedgedoc.org/t/image-upload-fail-docker/439
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
HedgeDoc crashed with
`uncaughtException: ENOENT: no such file or directory`
on startup, when `.git/ref/heads` did not contain
a file for the current branch. This seems to happen
regularly with current Git versions.
This fixes the crash by first trying to use the `git` executable for
getting the current commit SHA (before running our own parsing code)
and introducing a separate check to prevent accessing a nonexistent
file in `.git/ref/heads`.
Signed-off-by: David Mehren <git@herrmehren.de>
This patch implements 6 additional environment variables that are used
for configuration of the database in order to allow easier configuration
in containerised environments, such as Kubernetes.
An example is the upcoming deployment of the demo instance that will use
an operator-backed postgresql database. This operator exposes username
and password as separate variables and while it's obviously possible to
generate a dbURL from that, this won't be possible without additional
code. Aiming for a solution in Hedgedoc itself, will help us to enable
other people in using Hedgedoc on Kubernetes without resulting in overly
customised setups for simple tasks like this.
Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
According to the AWS documentation there is no situation that there is a dash in `s3-<region>.amazonaws.com`, the correct way is with a dot `s3.<region>.amazonaws.com`
Source: https://docs.aws.amazon.com/general/latest/gr/s3.html
Signed-off-by: Matej Cotman <matej.cotman@eficode.com>
This commit adds a `useUnless` helper method which can be used as a middleware for express.
It receives an express-middleware and an array of paths.
When a request matches one of the given paths, this middleware does nothing.
Otherwise the given middleware is called.
For the express-session middleware this helper middleware is used to avoid session creation on purely status routes.
See #1446
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
HedgeDoc displays the username and user photo at various places
by rendering the respective variables into an `ejs` template.
As the values are user-provided or generated from user-provided data,
it may be possible to inject unwanted HTML.
This commit sanitizes the username and photo URL by passing them
through the `xss` library.
Co-authored-by: Christoph (Sheogorath) Kern <sheogorath@shivering-isles.com>
Signed-off-by: David Mehren <git@herrmehren.de>
This makes the behavior consistent with the docs and
saves the user from having to both set
`useSSL` and `protocolUseSSL`.
Signed-off-by: David Mehren <git@herrmehren.de>
The `upgradeInsecureRequests` option of Helmets CSP middleware
was a boolean in Helmet 3, but with Helmet 4,
everything changed to lists.
This commit adjusts the addUpgradeUnsafeRequestsOptionTo
function accordingly.
Closes#1221
See also https://github.com/helmetjs/helmet/tree/v4.6.0/middlewares/content-security-policy
Signed-off-by: David Mehren <git@herrmehren.de>
This polyfill was added because node versions less than 10.5.0 didn't include scrypt support. As we now raised the minimum required version to 12.0.0, this polyfill isn't needed anymore.
Signed-off-by: Erik Michelson <opensource@erik.michelson.eu>
Impact
---
An attacker can read arbitrary `.md` files from the server's filesystem due to an [improper input validation](https://cwe.mitre.org/data/definitions/20.html), which results in the ability to perform a [relative path traversal](https://cwe.mitre.org/data/definitions/23.html).
CVSSv3 string: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
PoC / Quicktest
---
To verify if you are affected, you can try to open the following URL: `http://localhost:3000/..%2F..%2FREADME#` (replace `http://localhost:3000` with your instance's base-URL e.g. `https://demo.hedgedoc.org/..%2F..%2FREADME#`).
- If you see a README page being rendered, you run an affected version.
Analysis
---
The attack works due the fact that [the internal router, passes the url-encoded alias](https://github.com/hedgedoc/hedgedoc/blob/master/lib/web/note/router.js#L26) to the `noteController.showNote`-function. This function passes the input directly to [`findNote()`](78a732abe6/lib/web/note/util.js (L10)) utility function, that will pass it on the the [`parseNoteId()`](78a732abe6/lib/models/note.js (L188-L258))-function, that tries to make sense out of the noteId/alias and check if a note already exists and if so, if a corresponding file on disk was updated.
If no note exists the [note creation-function is called](78a732abe6/lib/models/note.js (L240-L245)), which pass this unvalidated alias, with a `.md` appended, into a [`path.join()`-function](78a732abe6/lib/models/note.js (L99)) which is read from the filesystem in the follow up routine and provides the pre-filled content of the new note.
This allows an attacker to not only read arbitrary `.md` files from the filesystem, but also observes changes to them.
The usefulness of this attack can be considered limited, since mainly markdown files are use the file-ending `.md` and all markdown files contained in the hedgedoc project, like the README, are public anyway. If other protections such as a chroot or container or proper file permissions are in place, this attack's usefulness is rather limited.
Workarounds
---
On a reverse-proxy level one can force a URL-decode, which will prevent this attack because the router will not accept such a path.
For more information
---
If you have any questions or comments about this advisory:
* Open an topic on [our community forum](https://community.hedgedoc.org)
* Join our [matrix room](https://chat.hedgedoc.org)
Advisory link
---
https://github.com/hedgedoc/hedgedoc/security/advisories/GHSA-p528-555r-pf87
Signed-off-by: Christoph (Sheogorath) Kern <sheogorath@shivering-isles.com>
This reuses the `realtime.getStatus` method to get the state of the
application state on every prometheus scrape cycle.
Signed-off-by: David Mehren <git@herrmehren.de>
Previously one could override notes in FreeURL-mode by sending multiple POST requests to the /new/<alias> endpoint. This commit adds a check for an already existing note with the requested alias and returns a HTTP 409 Conflict error in case that happens.
Signed-off-by: Erik Michelson <opensource@erik.michelson.eu>
This checks all files that claim to be an svg (by their extension) that they really are and defines the typeFromMagic accordingly
Files that got identified as jpg, but have the extension .jpeg get their extension fixed.
The files extensions will work in all cases now.
Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit removes the need for separate migrations with the sequelize-cli
by running them with umzug on application startup.
This is a port of #384
Co-authored-by: Sheogorath <sheogorath@shivering-isles.com>
Signed-off-by: David Mehren <git@herrmehren.de>