hedgedoc/backend/package.json
Erik Michelson f30f0d8e51 fix(passwords): use argon2id instead of bcrypt
OWASP [1] recommends for password hashing the following algorithms in
descending order: argon2id, scrypt, bcrypt. They state that bcrypt may
be used in legacy systems or when required due to legal regulations.
We're however not building any legacy application. Even HedgeDoc 1.x
utilizes a more modern algorithm by using scrypt.

While bcrypt is not insecure per se, our implementation had a major
security flaw, leading to invalid passwords being accepted in certain
cases. The bcrypt nodejs package - and the OWASP cheatsheet as well -
point out, that the maximum input length of passwords is limited to 72
bytes with bcrypt. When some user has a password longer than 72 bytes in
use, only the first 72 bytes are required to log in successfully.
Depending on the encoding (which could be UTF-8 or UTF-16 depending on
different circumstances) this could in worst-case be at 36 characters,
which is not very unusual for a password. See also [2].

This commit changes the used algorithm to argon2id. Argon2id has been in
use for several years now and seems to be a well-designed password
hashing function that even won the 2015 Password Hashing Competition.
Argon2 does not have any real-world max input length for passwords (it
is at 4 GiB).

The node-rs/argon2 implementation seems to be well maintained, widely
used (more than 150k downloads per week) and is published with
provenance, proving that the npm package was built on GitHub actions
using the source code in the repository. The implementation is written
in Rust, so it should be safe against memory leakages etc.

[1]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Che
     at_Sheet.html#password-hashing-algorithms
[2]: https://security.stackexchange.com/a/39851

Signed-off-by: Erik Michelson <github@erik.michelson.eu>
2024-08-08 20:29:23 +02:00

147 lines
4.6 KiB
JSON

{
"name": "@hedgedoc/backend",
"version": "2.0.0-alpha.2",
"description": "Realtime collaborative markdown notes on all platforms.",
"author": "",
"private": true,
"license": "AGPL-3.0",
"scripts": {
"build": "rimraf dist && nest build",
"format": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
"format:fix": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "rimraf dist && nest start",
"start:dev": "rimraf dist && nest start --watch",
"start:debug": "rimraf dist && nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint --max-warnings 0 \"{src,apps,libs,test}/**/*.ts\"",
"lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:ci": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config jest-e2e.json && rimraf test_uploads*",
"test:e2e:ci": "jest --config jest-e2e.json --coverage && rimraf test_uploads*",
"seed": "ts-node src/seed.ts",
"typeorm": "typeorm-ts-node-commonjs -d src/ormconfig.ts"
},
"dependencies": {
"@azure/storage-blob": "12.17.0",
"@hedgedoc/commons": "workspace:commons",
"@mrdrogdrog/optional": "1.2.1",
"@nestjs/common": "10.3.3",
"@nestjs/config": "3.2.0",
"@nestjs/core": "10.3.3",
"@nestjs/event-emitter": "2.0.4",
"@nestjs/passport": "10.0.3",
"@nestjs/platform-express": "10.3.3",
"@nestjs/platform-ws": "10.3.3",
"@nestjs/schedule": "4.0.1",
"@nestjs/swagger": "7.3.0",
"@nestjs/typeorm": "10.0.2",
"@nestjs/websockets": "10.3.3",
"@node-rs/argon2": "^1.8.3",
"@types/bcrypt": "5.0.2",
"@types/cron": "2.0.1",
"@types/minio": "7.1.0",
"@types/node-fetch": "2.6.11",
"@types/passport-http-bearer": "1.0.41",
"@zxcvbn-ts/core": "3.0.4",
"@zxcvbn-ts/language-common": "3.0.4",
"@zxcvbn-ts/language-en": "3.0.2",
"base32-encode": "1.2.0",
"class-transformer": "0.5.1",
"class-validator": "0.14.1",
"cli-color": "2.0.3",
"connect-typeorm": "2.0.0",
"cookie": "0.6.0",
"diff": "5.1.0",
"express-session": "1.18.0",
"file-type": "16.5.4",
"htmlparser2": "9.1.0",
"joi": "17.12.1",
"ldapauth-fork": "5.0.5",
"markdown-it": "13.0.2",
"minio": "7.1.3",
"mysql": "2.18.1",
"node-fetch": "2.7.0",
"passport": "0.7.0",
"passport-custom": "1.1.1",
"passport-http-bearer": "1.0.1",
"passport-local": "1.0.0",
"pg": "8.11.3",
"raw-body": "2.5.2",
"reflect-metadata": "0.2.1",
"rimraf": "5.0.5",
"rxjs": "7.8.1",
"sqlite3": "5.1.7",
"typeorm": "0.3.20",
"ws": "8.16.0",
"yjs": "13.6.12"
},
"devDependencies": {
"@darraghor/eslint-plugin-nestjs-typed": "4.5.0",
"@nestjs/cli": "10.3.2",
"@nestjs/schematics": "10.1.1",
"@nestjs/testing": "10.3.3",
"@trivago/prettier-plugin-sort-imports": "4.3.0",
"@tsconfig/node18": "18.2.2",
"@types/cli-color": "2.0.6",
"@types/cookie": "0.6.0",
"@types/cookie-signature": "1.1.2",
"@types/diff": "5.0.9",
"@types/express": "4.17.21",
"@types/express-session": "1.17.10",
"@types/jest": "29.5.12",
"@types/markdown-it": "13.0.7",
"@types/mysql": "2.15.25",
"@types/node": "20.11.18",
"@types/passport-local": "1.0.38",
"@types/pg": "8.11.0",
"@types/source-map-support": "0.5.10",
"@types/supertest": "2.0.16",
"@types/ws": "8.5.10",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jest": "27.9.0",
"eslint-plugin-local-rules": "2.0.1",
"eslint-plugin-prettier": "5.1.3",
"http-proxy-middleware": "2.0.6",
"jest": "29.7.0",
"mocked-env": "1.3.5",
"prettier": "3.2.5",
"source-map-support": "0.5.21",
"supertest": "6.3.4",
"ts-jest": "29.1.2",
"ts-mockery": "1.2.0",
"ts-node": "11.0.0-beta.1",
"tsconfig-paths": "4.2.0",
"typescript": "5.3.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": [
"ts-jest",
{
"tsconfig": "test/tsconfig.json"
}
]
},
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"reporters": [
"default",
"github-actions"
]
},
"packageManager": "yarn@4.1.0"
}